------------------------------------------------------------------------ r26240 | vda | 2009-04-29 07:02:57 -0500 (Wed, 29 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/miscutils/flash_eraseall.c M /trunk/busybox/networking/ifplugd.c M /trunk/busybox/networking/tc.c M /trunk/busybox/util-linux/mkfs_vfat.c *: bb_error_msg's messages should not be capitalized ------------------------------------------------------------------------ Index: networking/ifplugd.c =================================================================== --- networking/ifplugd.c (revision 26239) +++ networking/ifplugd.c (revision 26240) @@ -258,7 +258,7 @@ if (network_ioctl(SIOCGIFADDR, &ifrequest) < 0) { bb_error_msg("can't get interface address"); } else if (ifrequest.ifr_addr.sa_family != AF_INET) { - bb_perror_msg("The interface is not IP-based"); + bb_perror_msg("the interface is not IP-based"); } else { ((struct sockaddr_in*)(&ifrequest.ifr_addr))->sin_addr.s_addr = INADDR_ANY; if (network_ioctl(SIOCSIFADDR, &ifrequest) < 0) @@ -299,7 +299,7 @@ (uint8_t)(ifrequest.ifr_hwaddr.sa_data[5])); } - bb_error_msg("Using interface %s%s with driver<%s> (version: %s)", + bb_error_msg("using interface %s%s with driver<%s> (version: %s)", G.iface, buf, driver_info.driver, driver_info.version); } #endif Index: networking/tc.c =================================================================== --- networking/tc.c (revision 26239) +++ networking/tc.c (revision 26240) @@ -284,12 +284,12 @@ char *name; if (hdr->nlmsg_type != RTM_NEWQDISC && hdr->nlmsg_type != RTM_DELQDISC) { - /* bb_error_msg("Not a qdisc"); */ + /* bb_error_msg("not a qdisc"); */ return 0; /* ??? mimic upstream; should perhaps return -1 */ } len -= NLMSG_LENGTH(sizeof(*msg)); if (len < 0) { - /* bb_error_msg("Wrong len %d", len); */ + /* bb_error_msg("wrong len %d", len); */ return -1; } /* not the desired interface? */ @@ -342,12 +342,12 @@ /*XXX Eventually factor out common code */ if (hdr->nlmsg_type != RTM_NEWTCLASS && hdr->nlmsg_type != RTM_DELTCLASS) { - /* bb_error_msg("Not a class"); */ + /* bb_error_msg("not a class"); */ return 0; /* ??? mimic upstream; should perhaps return -1 */ } len -= NLMSG_LENGTH(sizeof(*msg)); if (len < 0) { - /* bb_error_msg("Wrong len %d", len); */ + /* bb_error_msg("wrong len %d", len); */ return -1; } /* not the desired interface? */ Index: miscutils/flash_eraseall.c =================================================================== --- miscutils/flash_eraseall.c (revision 26239) +++ miscutils/flash_eraseall.c (revision 26240) @@ -97,7 +97,7 @@ if (clmlen > 8) clmlen = 8; if (clmlen == 0) - bb_error_msg_and_die("Autoplacement selected and no empty space in oob"); + bb_error_msg_and_die("autoplacement selected and no empty space in oob"); } else { /* Legacy mode */ switch (meminfo.oobsize) { Index: util-linux/mkfs_vfat.c =================================================================== --- util-linux/mkfs_vfat.c (revision 26239) +++ util-linux/mkfs_vfat.c (revision 26240) @@ -273,10 +273,10 @@ device_num == 0x0d00 || // xd device_num == 0x1600 ) // hdc, hdd ) - bb_error_msg_and_die("Will not try to make filesystem on full-disk device (use -I if wanted)"); + bb_error_msg_and_die("will not try to make filesystem on full-disk device (use -I if wanted)"); // can't work on mounted filesystems if (find_mount_point(device_name, NULL)) - bb_error_msg_and_die("Can't format mounted filesystem"); + bb_error_msg_and_die("can't format mounted filesystem"); #endif // get true sector size // (parameter must be int*, not long* or size_t*) @@ -562,7 +562,7 @@ start_data_sector = (reserved_sect + NUM_FATS * sect_per_fat) * (bytes_per_sect / SECTOR_SIZE); start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / SECTORS_PER_BLOCK; - bb_info_msg("Searching for bad blocks "); + bb_info_msg("searching for bad blocks "); currently_testing = 0; try = TEST_BUFFER_BLOCKS; while (currently_testing < volume_size_blocks) { @@ -577,7 +577,7 @@ if (got < 0) got = 0; if (got & (BLOCK_SIZE - 1)) - bb_error_msg("Unexpected values in do_check: probably bugs"); + bb_error_msg("unexpected values in do_check: probably bugs"); got /= BLOCK_SIZE; currently_testing += got; if (got == try) { @@ -592,7 +592,7 @@ for (i = 0; i < SECTORS_PER_BLOCK; i++) { int cluster = (currently_testing * SECTORS_PER_BLOCK + i - start_data_sector) / (int) (sect_per_clust) / (bytes_per_sect / SECTOR_SIZE); if (cluster < 0) - bb_error_msg_and_die("Invalid cluster number in mark_sector: probably bug!"); + bb_error_msg_and_die("invalid cluster number in mark_sector: probably bug!"); MARK_CLUSTER(cluster, BAD_FAT32); } badblocks++; ------------------------------------------------------------------------ r26239 | vda | 2009-04-29 07:01:51 -0500 (Wed, 29 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/archival/Config.in M /trunk/busybox/archival/Kbuild A /trunk/busybox/archival/liblzo.h A /trunk/busybox/archival/liblzo_interface.h A /trunk/busybox/archival/lzo1x_1.c A /trunk/busybox/archival/lzo1x_1o.c A /trunk/busybox/archival/lzo1x_9x.c A /trunk/busybox/archival/lzo1x_c.c A /trunk/busybox/archival/lzo1x_d.c A /trunk/busybox/archival/lzop.c M /trunk/busybox/include/applets.h M /trunk/busybox/include/usage.h lzop: new applet. Busyboxed by Alain Knaff. +7700 bytes. ------------------------------------------------------------------------ Index: archival/liblzo.h =================================================================== --- archival/liblzo.h (revision 0) +++ archival/liblzo.h (revision 26239) @@ -0,0 +1,93 @@ +/* + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer+ http://www.oberhumer.com/opensource/lzo/ + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "liblzo_interface.h" + +/* lzo-2.03/src/config1x.h */ +#define M2_MIN_LEN 3 +#define M2_MAX_LEN 8 +#define M3_MAX_LEN 33 +#define M4_MAX_LEN 9 +#define M1_MAX_OFFSET 0x0400 +#define M2_MAX_OFFSET 0x0800 +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff +#define M1_MARKER 0 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) + +#define LZO_EOF_CODE + +/* lzo-2.03/src/lzo_dict.h */ +#define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#define DX2(p,s1,s2) \ + (((((unsigned)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +//#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +//#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) + +#define D_SIZE (1U << D_BITS) +#define D_MASK ((1U << D_BITS) - 1) +#define D_HIGH ((D_MASK >> 1) + 1) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + ( \ + m_pos = ip - (unsigned)(ip - m_pos), \ + ((uintptr_t)m_pos < (uintptr_t)in \ + || (m_off = (unsigned)(ip - m_pos)) <= 0 \ + || m_off > max_offset) \ + ) + +#define DENTRY(p,in) (p) +#define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) + +#define DMS(v,s) ((unsigned) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) ((unsigned) ((v) & D_MASK)) +#define DMUL(a,b) ((unsigned) ((a) * (b))) + +/* lzo-2.03/src/lzo_ptr.h */ +#define pd(a,b) ((unsigned)((a)-(b))) + +# define TEST_IP (ip < ip_end) +# define NEED_IP(x) \ + if ((unsigned)(ip_end - ip) < (unsigned)(x)) goto input_overrun + +# undef TEST_OP /* don't need both of the tests here */ +# define TEST_OP 1 +# define NEED_OP(x) \ + if ((unsigned)(op_end - op) < (unsigned)(x)) goto output_overrun + +#define HAVE_ANY_OP 1 + +//#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun +//# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun +//#else +//# define TEST_LB(m_pos) ((void) 0) +//# define TEST_LBO(m_pos,o) ((void) 0) +//#endif Index: archival/lzo1x_1o.c =================================================================== --- archival/lzo1x_1o.c (revision 0) +++ archival/lzo1x_1o.c (revision 26239) @@ -0,0 +1,35 @@ +/* LZO1X-1(15) compression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer + http://www.oberhumer.com/opensource/lzo/ + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "libbb.h" +#include "liblzo.h" + +#define D_BITS 15 +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#define DO_COMPRESS lzo1x_1_15_compress + +#include "lzo1x_c.c" Index: archival/lzo1x_c.c =================================================================== --- archival/lzo1x_c.c (revision 0) +++ archival/lzo1x_c.c (revision 26239) @@ -0,0 +1,296 @@ +/* implementation of the LZO1[XY]-1 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer + http://www.oberhumer.com/opensource/lzo/ + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/*********************************************************************** +// compress a block of data. +************************************************************************/ +static NOINLINE unsigned +do_compress(const uint8_t* in, unsigned in_len, + uint8_t* out, unsigned* out_len, + void* wrkmem) +{ + register const uint8_t* ip; + uint8_t* op; + const uint8_t* const in_end = in + in_len; + const uint8_t* const ip_end = in + in_len - M2_MAX_LEN - 5; + const uint8_t* ii; + const void* *const dict = (const void**) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += 4; + for (;;) { + register const uint8_t* m_pos; + unsigned m_off; + unsigned m_len; + unsigned dindex; + + D_INDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + D_INDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + + try_match: +#if 1 && defined(LZO_UNALIGNED_OK_2) + if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) +#endif + { + } else { + if (m_pos[2] == ip[2]) { +#if 0 + if (m_off <= M2_MAX_OFFSET) + goto match; + if (lit <= 3) + goto match; + if (lit == 3) { /* better compression, but slower */ + assert(op - 2 > out); op[-2] |= (uint8_t)(3); + *op++ = *ii++; *op++ = *ii++; *op++ = *ii++; + goto code_match; + } + if (m_pos[3] == ip[3]) +#endif + goto match; + } + else { + /* still need a better way for finding M1 matches */ +#if 0 + /* a M1 match */ +#if 0 + if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3) +#else + if (m_off <= M1_MAX_OFFSET && lit == 3) +#endif + { + register unsigned t; + + t = lit; + assert(op - 2 > out); op[-2] |= (uint8_t)(t); + do *op++ = *ii++; while (--t > 0); + assert(ii == ip); + m_off -= 1; + *op++ = (uint8_t)(M1_MARKER | ((m_off & 3) << 2)); + *op++ = (uint8_t)(m_off >> 2); + ip += 2; + goto match_done; + } +#endif + } + } + + /* a literal */ + literal: + UPDATE_I(dict, 0, dindex, ip, in); + ++ip; + if (ip >= ip_end) + break; + continue; + + /* a match */ +match: + UPDATE_I(dict, 0, dindex, ip, in); + /* store current literal run */ + if (pd(ip, ii) > 0) { + register unsigned t = pd(ip, ii); + + if (t <= 3) { + assert(op - 2 > out); + op[-2] |= (uint8_t)(t); + } + else if (t <= 18) + *op++ = (uint8_t)(t - 3); + else { + register unsigned tt = t - 18; + + *op++ = 0; + while (tt > 255) { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = (uint8_t)(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + /* code the match */ + assert(ii == ip); + ip += 3; + if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ + || m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++ +#ifdef LZO1Y + || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++ + || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++ +#endif + ) { + --ip; + m_len = pd(ip, ii); + assert(m_len >= 3); + assert(m_len <= M2_MAX_LEN); + + if (m_off <= M2_MAX_OFFSET) { + m_off -= 1; +#if defined(LZO1X) + *op++ = (uint8_t)(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = (uint8_t)(m_off >> 3); +#elif defined(LZO1Y) + *op++ = (uint8_t)(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = (uint8_t)(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) { + m_off -= 1; + *op++ = (uint8_t)(M3_MARKER | (m_len - 2)); + goto m3_m4_offset; + } else { +#if defined(LZO1X) + m_off -= 0x4000; + assert(m_off > 0); + assert(m_off <= 0x7fff); + *op++ = (uint8_t)(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2)); + goto m3_m4_offset; +#elif defined(LZO1Y) + goto m4_match; +#endif + } + } + else { + { + const uint8_t* end = in_end; + const uint8_t* m = m_pos + M2_MAX_LEN + 1; + while (ip < end && *m == *ip) + m++, ip++; + m_len = pd(ip, ii); + } + assert(m_len > M2_MAX_LEN); + + if (m_off <= M3_MAX_OFFSET) { + m_off -= 1; + if (m_len <= 33) + *op++ = (uint8_t)(M3_MARKER | (m_len - 2)); + else { + m_len -= 33; + *op++ = M3_MARKER | 0; + goto m3_m4_len; + } + } else { +#if defined(LZO1Y) + m4_match: +#endif + m_off -= 0x4000; + assert(m_off > 0); + assert(m_off <= 0x7fff); + if (m_len <= M4_MAX_LEN) + *op++ = (uint8_t)(M4_MARKER | ((m_off & 0x4000) >> 11) | (m_len - 2)); + else { + m_len -= M4_MAX_LEN; + *op++ = (uint8_t)(M4_MARKER | ((m_off & 0x4000) >> 11)); + m3_m4_len: + while (m_len > 255) { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = (uint8_t)(m_len); + } + } + m3_m4_offset: + *op++ = (uint8_t)((m_off & 63) << 2); + *op++ = (uint8_t)(m_off >> 6); + } +#if 0 + match_done: +#endif + ii = ip; + if (ip >= ip_end) + break; + } + + *out_len = pd(op, out); + return pd(in_end, ii); +} + +/*********************************************************************** +// public entry point +************************************************************************/ +int DO_COMPRESS(const uint8_t* in, unsigned in_len, + uint8_t* out, unsigned* out_len, + void* wrkmem) +{ + uint8_t* op = out; + unsigned t; + + if (in_len <= M2_MAX_LEN + 5) + t = in_len; + else { + t = do_compress(in,in_len,op,out_len,wrkmem); + op += *out_len; + } + + if (t > 0) { + const uint8_t* ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = (uint8_t)(17 + t); + else if (t <= 3) + op[-2] |= (uint8_t)(t); + else if (t <= 18) + *op++ = (uint8_t)(t - 3); + else { + unsigned tt = t - 18; + + *op++ = 0; + while (tt > 255) { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = (uint8_t)(tt); + } + do *op++ = *ii++; while (--t > 0); + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return 0; /*LZO_E_OK*/ +} Index: archival/lzo1x_d.c =================================================================== --- archival/lzo1x_d.c (revision 0) +++ archival/lzo1x_d.c (revision 26239) @@ -0,0 +1,420 @@ +/* implementation of the LZO1X decompression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer + http://www.oberhumer.com/opensource/lzo/ + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "libbb.h" +#include "liblzo.h" + +/*********************************************************************** +// decompress a block of data. +************************************************************************/ +/* safe decompression with overrun testing */ +int lzo1x_decompress_safe(const uint8_t* in, unsigned in_len, + uint8_t* out, unsigned* out_len, + void* wrkmem UNUSED_PARAM) +{ + register uint8_t* op; + register const uint8_t* ip; + register unsigned t; +#if defined(COPY_DICT) + unsigned m_off; + const uint8_t* dict_end; +#else + register const uint8_t* m_pos = NULL; /* possibly not needed */ +#endif + const uint8_t* const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + uint8_t* const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + unsigned last_m_off = 0; +#endif + +// LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) { + if (dict_len > M4_MAX_OFFSET) { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } else { + dict_len = 0; + dict_end = NULL; + } +#endif /* COPY_DICT */ + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+1); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) { + t = *ip++; + if (t >= 16) + goto match; + /* a literal run */ + if (t == 0) { + NEED_IP(1); + while (*ip == 0) { + t += 255; + ip++; + NEED_IP(1); + } + t += 15 + *ip++; + } + /* copy literals */ + assert(t > 0); + NEED_OP(t+3); + NEED_IP(t+4); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +# if !defined(LZO_UNALIGNED_OK_4) + if (PTR_ALIGNED2_4(op, ip)) +# endif + { + COPY4(op, ip); + op += 4; + ip += 4; + if (--t > 0) { + if (t >= 4) { + do { + COPY4(op, ip); + op += 4; + ip += 4; + t -= 4; + } while (t >= 4); + if (t > 0) + do *op++ = *ip++; while (--t > 0); + } else { + do *op++ = *ip++; while (--t > 0); + } + } + } +# if !defined(LZO_UNALIGNED_OK_4) + else +# endif +#endif +#if !defined(LZO_UNALIGNED_OK_4) + { + *op++ = *ip++; + *op++ = *ip++; + *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + + first_literal_run: + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else /* !COPY_DICT */ +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *m_pos; +#endif /* COPY_DICT */ + goto match_done; + + /* handle matches */ + do { + match: + if (t >= 64) { /* a M2 match */ +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else /* !COPY_DICT */ +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + unsigned off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) { + assert(last_m_off > 0); + m_pos -= last_m_off; + } else { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif /* COPY_DICT */ + } + else if (t >= 32) { /* a M3 match */ + t &= 31; + if (t == 0) { + NEED_IP(1); + while (*ip == 0) { + t += 255; + ip++; + NEED_IP(1); + } + t += 31 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else /* !COPY_DICT */ +#if defined(LZO1Z) + { + unsigned off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif /* COPY_DICT */ + ip += 2; + } + else if (t >= 16) { /* a M4 match */ +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else /* !COPY_DICT */ + m_pos = op; + m_pos -= (t & 8) << 11; +#endif /* COPY_DICT */ + t &= 7; + if (t == 0) { + NEED_IP(1); + while (*ip == 0) { + t += 255; + ip++; + NEED_IP(1); + } + t += 7 + *ip++; + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else /* !COPY_DICT */ +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN) + m_pos -= (* (const lzo_ushortp) ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const uint8_t*)op, m_pos); +#endif +#endif /* COPY_DICT */ + } + else { /* a M1 match */ +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else /* !COPY_DICT */ +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; + *op++ = *m_pos; +#endif /* COPY_DICT */ + goto match_done; + } + + /* copy match */ +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else /* !COPY_DICT */ + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) +# if !defined(LZO_UNALIGNED_OK_4) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) { + assert((op - m_pos) >= 4); /* both pointers are aligned */ +# else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) { +# endif + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) + do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { + copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif /* COPY_DICT */ + + match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + + /* copy literals */ + match_next: + assert(t > 0); + assert(t < 4); + NEED_OP(t); + NEED_IP(t+1); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { + *op++ = *ip++; + if (t > 2) + *op++ = *ip++; + } +#endif + t = *ip++; + } while (TEST_IP && TEST_OP); + } + +//#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) + /* no EOF code was found */ + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; +//#endif + + eof_found: + assert(t == 1); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +//#if defined(HAVE_NEED_IP) + input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +//#endif + +//#if defined(HAVE_NEED_OP) + output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +//#endif + +//#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) + lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +//#endif +} Index: archival/liblzo_interface.h =================================================================== --- archival/liblzo_interface.h (revision 0) +++ archival/liblzo_interface.h (revision 26239) @@ -0,0 +1,71 @@ +/* + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer + http://www.oberhumer.com/opensource/lzo/ + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#define LZO1X +#undef LZO1Y + +#undef assert +/* +static void die_at(int line) +{ + bb_error_msg_and_die("internal error at %d", line); +} +#define assert(v) if (!(v)) die_at(__LINE__) +*/ +#define assert(v) ((void)0) + +int lzo1x_1_compress(const uint8_t* src, unsigned src_len, + uint8_t* dst, unsigned* dst_len, + void* wrkmem); +int lzo1x_1_15_compress(const uint8_t* src, unsigned src_len, + uint8_t* dst, unsigned* dst_len, + void* wrkmem); +int lzo1x_999_compress_level(const uint8_t* in, unsigned in_len, + uint8_t* out, unsigned* out_len, + void* wrkmem, + int compression_level); + +/* decompression */ +//int lzo1x_decompress(const uint8_t* src, unsigned src_len, +// uint8_t* dst, unsigned* dst_len, +// void* wrkmem /* NOT USED */); +/* safe decompression with overrun testing */ +int lzo1x_decompress_safe(const uint8_t* src, unsigned src_len, + uint8_t* dst, unsigned* dst_len, + void* wrkmem /* NOT USED */); + +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [not used right now] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ + +/* lzo-2.03/include/lzo/lzoconf.h */ +#define LZO_VERSION 0x2030 Index: archival/lzop.c =================================================================== --- archival/lzop.c (revision 0) +++ archival/lzop.c (revision 26239) @@ -0,0 +1,1075 @@ +/* + This file is part of the lzop file compressor. + + Copyright (C) 1996..2003 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer + http://www.oberhumer.com/opensource/lzop/ + + lzop and the LZO library are free software; you can redistribute them + and/or modify them under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + "Minimalized" for busybox by Alain Knaff +*/ + +#include "libbb.h" +#include "unarchive.h" +#include "liblzo_interface.h" + +/* lzo-2.03/src/lzo_ptr.h */ +#define pd(a,b) ((unsigned)((a)-(b))) + +#define lzo_version() LZO_VERSION +#define lzo_sizeof_dict_t (sizeof(uint8_t*)) + +/* lzo-2.03/include/lzo/lzo1x.h */ +#define LZO1X_1_MEM_COMPRESS (16384 * lzo_sizeof_dict_t) +#define LZO1X_1_15_MEM_COMPRESS (32768 * lzo_sizeof_dict_t) +#define LZO1X_999_MEM_COMPRESS (14 * 16384 * sizeof(short)) + +/* lzo-2.03/src/lzo1x_oo.c */ +#define NO_LIT UINT_MAX + +/**********************************************************************/ +static void copy2(uint8_t* ip, const uint8_t* m_pos, unsigned off) +{ + ip[0] = m_pos[0]; + if (off == 1) + ip[1] = m_pos[0]; + else + ip[1] = m_pos[1]; +} + +static void copy3(uint8_t* ip, const uint8_t* m_pos, unsigned off) +{ + ip[0] = m_pos[0]; + if (off == 1) { + ip[2] = ip[1] = m_pos[0]; + } + else if (off == 2) { + ip[1] = m_pos[1]; + ip[2] = m_pos[0]; + } + else { + ip[1] = m_pos[1]; + ip[2] = m_pos[2]; + } +} + +/**********************************************************************/ +// optimize a block of data. +/**********************************************************************/ +#define TEST_IP (ip < ip_end) +#define TEST_OP (op <= op_end) + +static int lzo1x_optimize(uint8_t *in, unsigned in_len, + uint8_t *out, unsigned *out_len, + void* wrkmem UNUSED_PARAM) +{ + uint8_t* op; + uint8_t* ip; + unsigned t; + uint8_t* m_pos; + uint8_t* const ip_end = in + in_len; + uint8_t* const op_end = out + *out_len; + uint8_t* litp = NULL; + unsigned lit = 0; + unsigned next_lit = NO_LIT; + unsigned nl; + unsigned long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0; + +// LZO_UNUSED(wrkmem); + + *out_len = 0; + + op = out; + ip = in; + + if (*ip > 17) { + t = *ip++ - 17; + if (t < 4) + goto match_next; + goto first_literal_run; + } + + while (TEST_IP && TEST_OP) { + t = *ip++; + if (t >= 16) + goto match; + /* a literal run */ + litp = ip - 1; + if (t == 0) { + t = 15; + while (*ip == 0) + t += 255, ip++; + t += *ip++; + } + lit = t + 3; + /* copy literals */ + copy_literal_run: + *op++ = *ip++; + *op++ = *ip++; + *op++ = *ip++; + first_literal_run: + do *op++ = *ip++; while (--t > 0); + + t = *ip++; + + if (t >= 16) + goto match; +#if defined(LZO1X) + m_pos = op - 1 - 0x800; +#elif defined(LZO1Y) + m_pos = op - 1 - 0x400; +#endif + m_pos -= t >> 2; + m_pos -= *ip++ << 2; + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *m_pos++; + lit = 0; + goto match_done; + + + /* handle matches */ + do { + if (t < 16) { /* a M1 match */ + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; + + if (litp == NULL) + goto copy_m1; + + nl = ip[-2] & 3; + /* test if a match follows */ + if (nl == 0 && lit == 1 && ip[0] >= 16) { + next_lit = nl; + /* adjust length of previous short run */ + lit += 2; + *litp = (unsigned char)((*litp & ~3) | lit); + /* copy over the 2 literals that replace the match */ + copy2(ip-2, m_pos, pd(op, m_pos)); + o_m1_a++; + } + /* test if a literal run follows */ + else if (nl == 0 && ip[0] < 16 && ip[0] != 0 && + (lit + 2 + ip[0] < 16)) + { + t = *ip++; + /* remove short run */ + *litp &= ~3; + /* copy over the 2 literals that replace the match */ + copy2(ip-3+1,m_pos,pd(op,m_pos)); + /* move literals 1 byte ahead */ + litp += 2; + if (lit > 0) + memmove(litp+1, litp, lit); + /* insert new length of long literal run */ + lit += 2 + t + 3; + *litp = (unsigned char)(lit - 3); + + o_m1_b++; + *op++ = *m_pos++; *op++ = *m_pos++; + goto copy_literal_run; + } + copy_m1: + *op++ = *m_pos++; + *op++ = *m_pos++; + } else { + match: + if (t >= 64) { /* a M2 match */ + m_pos = op - 1; +#if defined(LZO1X) + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#endif + if (litp == NULL) + goto copy_m; + + nl = ip[-2] & 3; + /* test if in beetween two long literal runs */ + if (t == 1 && lit > 3 && nl == 0 + && ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16) + ) { + t = *ip++; + /* copy over the 3 literals that replace the match */ + copy3(ip-1-2,m_pos,pd(op,m_pos)); + /* set new length of previous literal run */ + lit += 3 + t + 3; + *litp = (unsigned char)(lit - 3); + o_m2++; + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *m_pos++; + goto copy_literal_run; + } + } else { + if (t >= 32) { /* a M3 match */ + t &= 31; + if (t == 0) { + t = 31; + while (*ip == 0) + t += 255, ip++; + t += *ip++; + } + m_pos = op - 1; + m_pos -= *ip++ >> 2; + m_pos -= *ip++ << 6; + } else { /* a M4 match */ + m_pos = op; + m_pos -= (t & 8) << 11; + t &= 7; + if (t == 0) { + t = 7; + while (*ip == 0) + t += 255, ip++; + t += *ip++; + } + m_pos -= *ip++ >> 2; + m_pos -= *ip++ << 6; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; + } + if (litp == NULL) + goto copy_m; + + nl = ip[-2] & 3; + /* test if in beetween two matches */ + if (t == 1 && lit == 0 && nl == 0 && ip[0] >= 16) { + next_lit = nl; + /* make a previous short run */ + lit += 3; + *litp = (unsigned char)((*litp & ~3) | lit); + /* copy over the 3 literals that replace the match */ + copy3(ip-3,m_pos,pd(op,m_pos)); + o_m3_a++; + } + /* test if a literal run follows */ + else if (t == 1 && lit <= 3 && nl == 0 + && ip[0] < 16 && ip[0] != 0 && (lit + 3 + ip[0] < 16) + ) { + t = *ip++; + /* remove short run */ + *litp &= ~3; + /* copy over the 3 literals that replace the match */ + copy3(ip-4+1,m_pos,pd(op,m_pos)); + /* move literals 1 byte ahead */ + litp += 2; + if (lit > 0) + memmove(litp+1,litp,lit); + /* insert new length of long literal run */ + lit += 3 + t + 3; + *litp = (unsigned char)(lit - 3); + + o_m3_b++; + *op++ = *m_pos++; + *op++ = *m_pos++; + *op++ = *m_pos++; + goto copy_literal_run; + } + } + copy_m: + *op++ = *m_pos++; + *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + + match_done: + if (next_lit == NO_LIT) { + t = ip[-2] & 3; + lit = t; + litp = ip - 2; + } + else + t = next_lit; + next_lit = NO_LIT; + if (t == 0) + break; + /* copy literals */ + match_next: + do *op++ = *ip++; while (--t > 0); + t = *ip++; + } while (TEST_IP && TEST_OP); + } + + /* no EOF code was found */ + *out_len = pd(op, out); + return LZO_E_EOF_NOT_FOUND; + + eof_found: +// LZO_UNUSED(o_m1_a); LZO_UNUSED(o_m1_b); LZO_UNUSED(o_m2); +// LZO_UNUSED(o_m3_a); LZO_UNUSED(o_m3_b); + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); +} + +/**********************************************************************/ +#define F_OS F_OS_UNIX +#define F_CS F_CS_NATIVE + +/**********************************************************************/ +#define ADLER32_INIT_VALUE 1 +#define CRC32_INIT_VALUE 0 + +/**********************************************************************/ +enum { + M_LZO1X_1 = 1, + M_LZO1X_1_15 = 2, + M_LZO1X_999 = 3, +}; + +/**********************************************************************/ +/* header flags */ +#define F_ADLER32_D 0x00000001L +#define F_ADLER32_C 0x00000002L +#define F_H_EXTRA_FIELD 0x00000040L +#define F_H_GMTDIFF 0x00000080L +#define F_CRC32_D 0x00000100L +#define F_CRC32_C 0x00000200L +#define F_H_FILTER 0x00000800L +#define F_H_CRC32 0x00001000L +#define F_MASK 0x00003FFFL + +/* operating system & file system that created the file [mostly unused] */ +#define F_OS_UNIX 0x03000000L +#define F_OS_SHIFT 24 +#define F_OS_MASK 0xff000000L + +/* character set for file name encoding [mostly unused] */ +#define F_CS_NATIVE 0x00000000L +#define F_CS_SHIFT 20 +#define F_CS_MASK 0x00f00000L + +/* these bits must be zero */ +#define F_RESERVED ((F_MASK | F_OS_MASK | F_CS_MASK) ^ 0xffffffffL) + +typedef struct chksum_t { + uint32_t f_adler32; + uint32_t f_crc32; +} chksum_t; + +typedef struct header_t { + unsigned version; + unsigned lib_version; + unsigned version_needed_to_extract; + uint32_t flags; + uint32_t mode; + uint32_t mtime; + uint32_t gmtdiff; + uint32_t header_checksum; + + uint32_t extra_field_len; + uint32_t extra_field_checksum; + + unsigned char method; + unsigned char level; + + /* info */ + char name[255+1]; +} header_t; + +struct globals { + const uint32_t *lzo_crc32_table; + chksum_t chksum_in; + chksum_t chksum_out; +}; +#define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { } while (0) +//#define G (*ptr_to_globals) +//#define INIT_G() do { +// SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); +//} while (0) + + +/**********************************************************************/ +#define LZOP_VERSION 0x1010 +//#define LZOP_VERSION_STRING "1.01" +//#define LZOP_VERSION_DATE "Apr 27th 2003" + +#define OPTION_STRING "cfvdt123456789CF" + +enum { + OPT_STDOUT = (1 << 0), + OPT_FORCE = (1 << 1), + OPT_VERBOSE = (1 << 2), + OPT_DECOMPRESS = (1 << 3), + OPT_TEST = (1 << 4), + OPT_1 = (1 << 5), + OPT_2 = (1 << 6), + OPT_3 = (1 << 7), + OPT_4 = (1 << 8), + OPT_5 = (1 << 9), + OPT_6 = (1 << 10), + OPT_789 = (7 << 11), + OPT_7 = (1 << 11), + OPT_8 = (1 << 12), + OPT_C = (1 << 14), + OPT_F = (1 << 15), +}; + +/**********************************************************************/ +// adler32 checksum +// adapted from free code by Mark Adler +// see http://www.zlib.org/ +/**********************************************************************/ +static FAST_FUNC uint32_t +lzo_adler32(uint32_t adler, const uint8_t* buf, unsigned len) +{ + enum { + LZO_BASE = 65521, /* largest prime smaller than 65536 */ + /* NMAX is the largest n such that + * 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + LZO_NMAX = 5552, + }; + uint32_t s1 = adler & 0xffff; + uint32_t s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +static FAST_FUNC uint32_t +lzo_crc32(uint32_t c, const uint8_t* buf, unsigned len) +{ + uint32_t crc; + + if (buf == NULL) + return 0; + + crc = ~c; + if (len != 0) do { + crc = G.lzo_crc32_table[((int)crc ^ *buf) & 0xff] ^ (crc >> 8); + buf += 1; + len -= 1; + } while (len > 0); + + return ~crc; +} + +/**********************************************************************/ +static void init_chksum(chksum_t *ct) +{ + ct->f_adler32 = ADLER32_INIT_VALUE; + ct->f_crc32 = CRC32_INIT_VALUE; +} + +static void add_bytes_to_chksum(chksum_t *ct, const void* buf, int cnt) +{ + /* We need to handle the two checksums at once, because at the + * beginning of the header, we don't know yet which one we'll + * eventually need */ + ct->f_adler32 = lzo_adler32(ct->f_adler32, (const uint8_t*)buf, cnt); + ct->f_crc32 = lzo_crc32(ct->f_crc32, (const uint8_t*)buf, cnt); +} + +static uint32_t chksum_getresult(chksum_t *ct, const header_t *h) +{ + return (h->flags & F_H_CRC32) ? ct->f_crc32 : ct->f_adler32; +} + +/**********************************************************************/ +static uint32_t read32(void) +{ + uint32_t v; + xread(0, &v, 4); + return ntohl(v); +} + +static void write32(uint32_t v) +{ + v = htonl(v); + xwrite(1, &v, 4); +} + +static void f_write(const void* buf, int cnt) +{ + xwrite(1, buf, cnt); + add_bytes_to_chksum(&G.chksum_out, buf, cnt); +} + +static void f_read(void* buf, int cnt) +{ + xread(0, buf, cnt); + add_bytes_to_chksum(&G.chksum_in, buf, cnt); +} + +static int f_read8(void) +{ + uint8_t v; + f_read(&v, 1); + return v; +} + +static void f_write8(uint8_t v) +{ + f_write(&v, 1); +} + +static unsigned f_read16(void) +{ + uint16_t v; + f_read(&v, 2); + return ntohs(v); +} + +static void f_write16(uint16_t v) +{ + v = htons(v); + f_write(&v, 2); +} + +static uint32_t f_read32(void) +{ + uint32_t v; + f_read(&v, 4); + return ntohl(v); +} + +static void f_write32(uint32_t v) +{ + v = htonl(v); + f_write(&v, 4); +} + +/**********************************************************************/ +static int lzo_get_method(header_t *h) +{ + /* check method */ + if (h->method == M_LZO1X_1) { + if (h->level == 0) + h->level = 3; + } else if (h->method == M_LZO1X_1_15) { + if (h->level == 0) + h->level = 1; + } else if (h->method == M_LZO1X_999) { + if (h->level == 0) + h->level = 9; + } else + return -1; /* not a LZO method */ + + /* check compression level */ + if (h->level < 1 || h->level > 9) + return 15; + + return 0; +} + +/**********************************************************************/ +#define LZO_BLOCK_SIZE (256 * 1024l) +#define MAX_BLOCK_SIZE (64 * 1024l * 1024l) /* DO NOT CHANGE */ + +/* LZO may expand uncompressible data by a small amount */ +#define MAX_COMPRESSED_SIZE(x) ((x) + (x) / 16 + 64 + 3) + +/**********************************************************************/ +// compress a file +/**********************************************************************/ +static smallint lzo_compress(const header_t *h) +{ + unsigned block_size = LZO_BLOCK_SIZE; + int r = 0; /* LZO_E_OK */ + uint8_t *const b1 = xzalloc(block_size); + uint8_t *const b2 = xzalloc(MAX_COMPRESSED_SIZE(block_size)); + unsigned src_len = 0, dst_len = 0; + uint32_t d_adler32 = ADLER32_INIT_VALUE; + uint32_t d_crc32 = CRC32_INIT_VALUE; + int l; + smallint ok = 1; + uint8_t *wrk_mem = NULL; + + if (h->method == M_LZO1X_1) + wrk_mem = xzalloc(LZO1X_1_MEM_COMPRESS); + else if (h->method == M_LZO1X_1_15) + wrk_mem = xzalloc(LZO1X_1_15_MEM_COMPRESS); + else if (h->method == M_LZO1X_999) + wrk_mem = xzalloc(LZO1X_999_MEM_COMPRESS); + + for (;;) { + /* read a block */ + l = full_read(0, b1, block_size); + src_len = (l > 0 ? l : 0); + + /* write uncompressed block size */ + write32(src_len); + + /* exit if last block */ + if (src_len == 0) + break; + + /* compute checksum of uncompressed block */ + if (h->flags & F_ADLER32_D) + d_adler32 = lzo_adler32(ADLER32_INIT_VALUE, b1, src_len); + if (h->flags & F_CRC32_D) + d_crc32 = lzo_crc32(CRC32_INIT_VALUE, b1, src_len); + + /* compress */ + if (h->method == M_LZO1X_1) + r = lzo1x_1_compress(b1, src_len, b2, &dst_len, wrk_mem); + else if (h->method == M_LZO1X_1_15) + r = lzo1x_1_15_compress(b1, src_len, b2, &dst_len, wrk_mem); +#if ENABLE_LZOP_COMPR_HIGH + else if (h->method == M_LZO1X_999) + r = lzo1x_999_compress_level(b1, src_len, b2, &dst_len, + wrk_mem, h->level); +#endif + else + bb_error_msg_and_die("internal error"); + + if (r != 0) /* not LZO_E_OK */ + bb_error_msg_and_die("internal error - compression failed"); + + /* write compressed block size */ + if (dst_len < src_len) { + /* optimize */ + if (h->method == M_LZO1X_999) { + unsigned new_len = src_len; + r = lzo1x_optimize(b2, dst_len, b1, &new_len, NULL); + if (r != 0 /*LZO_E_OK*/ || new_len != src_len) + bb_error_msg_and_die("internal error - optimization failed"); + } + write32(dst_len); + } else { + /* data actually expanded => store data uncompressed */ + write32(src_len); + } + + /* write checksum of uncompressed block */ + if (h->flags & F_ADLER32_D) + write32(d_adler32); + if (h->flags & F_CRC32_D) + write32(d_crc32); + + if (dst_len < src_len) { + /* write checksum of compressed block */ + if (h->flags & F_ADLER32_C) + write32(lzo_adler32(ADLER32_INIT_VALUE, b2, + dst_len)); + if (h->flags & F_CRC32_C) + write32(lzo_crc32(CRC32_INIT_VALUE, b2, dst_len)); + /* write compressed block data */ + xwrite(1, b2, dst_len); + } else { + /* write uncompressed block data */ + xwrite(1, b1, src_len); + } + } + + free(wrk_mem); + free(b1); + free(b2); + return ok; +} + +static void lzo_check(uint32_t FAST_FUNC (*fn)(uint32_t, const uint8_t*, unsigned), + uint32_t ref, uint32_t init, + uint8_t* buf, unsigned len) +{ + uint32_t c = fn(init, buf, len); + if (c != ref) + bb_error_msg_and_die("checksum error"); +} + +/**********************************************************************/ +// decompress a file +/**********************************************************************/ +static smallint lzo_decompress(const header_t *h) +{ + unsigned block_size = LZO_BLOCK_SIZE; + int r; + uint32_t src_len, dst_len; + uint32_t c_adler32 = ADLER32_INIT_VALUE; + uint32_t d_adler32 = ADLER32_INIT_VALUE; + uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; + smallint ok = 1; + uint8_t *b1; + uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); + uint8_t *b2 = NULL; + + for (;;) { + uint8_t *dst; + + /* read uncompressed block size */ + dst_len = read32(); + + /* exit if last block */ + if (dst_len == 0) + break; + + /* error if split file */ + if (dst_len == 0xffffffffL) + /* should not happen - not yet implemented */ + bb_error_msg_and_die("this file is a split lzop file"); + + if (dst_len > MAX_BLOCK_SIZE) + bb_error_msg_and_die("lzop file corrupted"); + + /* read compressed block size */ + src_len = read32(); + if (src_len <= 0 || src_len > dst_len) + bb_error_msg_and_die("lzop file corrupted"); + + if (dst_len > block_size) { + if (b2) { +//FIXME! + b2 = NULL; + free(b2); + } + block_size = dst_len; + mcs_block_size = MAX_COMPRESSED_SIZE(block_size); + } + + /* read checksum of uncompressed block */ + if (h->flags & F_ADLER32_D) + d_adler32 = read32(); + if (h->flags & F_CRC32_D) + d_crc32 = read32(); + + /* read checksum of compressed block */ + if (src_len < dst_len) { + if (h->flags & F_ADLER32_C) + c_adler32 = read32(); + if (h->flags & F_CRC32_C) + c_crc32 = read32(); + } + + if (b2 == NULL) + b2 = xzalloc(mcs_block_size); + /* read the block into the end of our buffer */ + b1 = b2 + mcs_block_size - src_len; + xread(0, b1, src_len); + + if (src_len < dst_len) { + unsigned d = dst_len; + + if (!(option_mask32 & OPT_F)) { + /* verify checksum of compressed block */ + if (h->flags & F_ADLER32_C) + lzo_check(lzo_adler32, c_adler32, + ADLER32_INIT_VALUE, + b1, src_len); + if (h->flags & F_CRC32_C) + lzo_check(lzo_crc32, c_crc32, + CRC32_INIT_VALUE, + b1, src_len); + } + + /* decompress */ +// if (option_mask32 & OPT_F) +// r = lzo1x_decompress(b1, src_len, b2, &d, NULL); +// else + r = lzo1x_decompress_safe(b1, src_len, b2, &d, NULL); + + if (r != 0 /*LZO_E_OK*/ || dst_len != d) { + bb_error_msg_and_die("corrupted compressed data"); + } + dst = b2; + } else { + /* "stored" block => no decompression */ + dst = b1; + } + + if (!(option_mask32 & OPT_F)) { + /* verify checksum of uncompressed block */ + if (h->flags & F_ADLER32_D) + lzo_check(lzo_adler32, d_adler32, ADLER32_INIT_VALUE, + dst, dst_len); + if (h->flags & F_CRC32_D) + lzo_check(lzo_crc32, d_crc32, CRC32_INIT_VALUE, + dst, dst_len); + } + + /* write uncompressed block data */ + xwrite(1, dst, dst_len); + } + + free(b2); + return ok; +} + +/**********************************************************************/ +// lzop file signature (shamelessly borrowed from PNG) +/**********************************************************************/ +/* + * The first nine bytes of a lzop file always contain the following values: + * + * 0 1 2 3 4 5 6 7 8 + * --- --- --- --- --- --- --- --- --- + * (hex) 89 4c 5a 4f 00 0d 0a 1a 0a + * (decimal) 137 76 90 79 0 13 10 26 10 + * (C notation - ASCII) \211 L Z O \0 \r \n \032 \n + */ + +/* (vda) comparison with lzop v1.02rc1 ("lzop -1 version); + f_write16(h->lib_version); + f_write16(h->version_needed_to_extract); + f_write8(h->method); + f_write8(h->level); + f_write32(h->flags); + f_write32(h->mode); + f_write32(h->mtime); + f_write32(h->gmtdiff); + + l = (int) strlen(h->name); + f_write8(l); + if (l) + f_write(h->name, l); + + f_write32(chksum_getresult(&G.chksum_out, h)); +} + +static int read_header(header_t *h) +{ + int r; + int l; + uint32_t checksum; + + memset(h, 0, sizeof(*h)); + h->version_needed_to_extract = 0x0900; /* first lzop version */ + h->level = 0; + + init_chksum(&G.chksum_in); + + h->version = f_read16(); + if (h->version < 0x0900) + return 3; + h->lib_version = f_read16(); + if (h->version >= 0x0940) { + h->version_needed_to_extract = f_read16(); + if (h->version_needed_to_extract > LZOP_VERSION) + return 16; + if (h->version_needed_to_extract < 0x0900) + return 3; + } + h->method = f_read8(); + if (h->version >= 0x0940) + h->level = f_read8(); + h->flags = f_read32(); + if (h->flags & F_H_FILTER) + return 16; /* filter not supported */ + h->mode = f_read32(); + h->mtime = f_read32(); + if (h->version >= 0x0940) + h->gmtdiff = f_read32(); + + l = f_read8(); + if (l > 0) + f_read(h->name, l); + h->name[l] = 0; + + checksum = chksum_getresult(&G.chksum_in, h); + h->header_checksum = f_read32(); + if (h->header_checksum != checksum) + return 2; + + if (h->method <= 0) + return 14; + r = lzo_get_method(h); + if (r != 0) + return r; + + /* check reserved flags */ + if (h->flags & F_RESERVED) + return -13; + + /* skip extra field [not used yet] */ + if (h->flags & F_H_EXTRA_FIELD) { + uint32_t k; + + /* note: the checksum also covers the length */ + init_chksum(&G.chksum_in); + h->extra_field_len = f_read32(); + for (k = 0; k < h->extra_field_len; k++) + f_read8(); + checksum = chksum_getresult(&G.chksum_in, h); + h->extra_field_checksum = f_read32(); + if (h->extra_field_checksum != checksum) + return 3; + } + + return 0; +} + +static void p_header(header_t *h) +{ + int r; + + r = read_header(h); + if (r == 0) + return; + bb_error_msg_and_die("header_error %d", r); +} + +/**********************************************************************/ +// compress +/**********************************************************************/ +static void lzo_set_method(header_t *h) +{ + int level = 1; + + if (option_mask32 & OPT_1) { + h->method = M_LZO1X_1_15; + } else if (option_mask32 & OPT_789) { +#if ENABLE_LZOP_COMPR_HIGH + h->method = M_LZO1X_999; + if (option_mask32 & OPT_7) + level = 7; + else if (option_mask32 & OPT_8) + level = 8; + else + level = 9; +#else + bb_error_msg_and_die("high compression not compiled in"); +#endif + } else { /* levels 2..6 or none (defaults to level 3) */ + h->method = M_LZO1X_1; + level = 5; /* levels 2-6 are actually the same */ + } + + h->level = level; +} + +static smallint do_lzo_compress(void) +{ + header_t header; + +#define h (&header) + memset(h, 0, sizeof(*h)); + + lzo_set_method(h); + + h->version = (LZOP_VERSION & 0xffff); + h->version_needed_to_extract = 0x0940; + h->lib_version = lzo_version() & 0xffff; + + h->flags = (F_OS & F_OS_MASK) | (F_CS & F_CS_MASK); + + if (!(option_mask32 & OPT_F) || h->method == M_LZO1X_999) { + h->flags |= F_ADLER32_D; + if (option_mask32 & OPT_C) + h->flags |= F_ADLER32_C; + } + write_header(h); + return lzo_compress(h); +#undef h +} + +/**********************************************************************/ +// decompress +/**********************************************************************/ +static smallint do_lzo_decompress(void) +{ + header_t header; + + check_magic(); + p_header(&header); + return lzo_decompress(&header); +} + +static char* make_new_name_lzop(char *filename) +{ + if (option_mask32 & OPT_DECOMPRESS) { + char *extension = strrchr(filename, '.'); + if (!extension || strcmp(extension + 1, "lzo") != 0) + return xasprintf("%s.out", filename); + *extension = '\0'; + return filename; + } + return xasprintf("%s.lzo", filename); +} + +static IF_DESKTOP(long long) int pack_lzop(unpack_info_t *info UNUSED_PARAM) +{ + if (option_mask32 & OPT_DECOMPRESS) + return do_lzo_decompress(); + return do_lzo_compress(); +} + +int lzop_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int lzop_main(int argc UNUSED_PARAM, char **argv) +{ + getopt32(argv, OPTION_STRING); + argv += optind; + /* lzopcat? */ + if (applet_name[4] == 'c') + option_mask32 |= (OPT_STDOUT | OPT_DECOMPRESS); + /* unlzop? */ + if (applet_name[0] == 'u') + option_mask32 |= OPT_DECOMPRESS; + + G.lzo_crc32_table = crc32_filltable(NULL, 0); + return bbunpack(argv, make_new_name_lzop, pack_lzop); +} Index: archival/Kbuild =================================================================== --- archival/Kbuild (revision 26238) +++ archival/Kbuild (revision 26239) @@ -16,6 +16,8 @@ lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o lib-$(CONFIG_GUNZIP) += bbunzip.o lib-$(CONFIG_GZIP) += gzip.o bbunzip.o +lib-$(CONFIG_LZOP) += lzop.o lzo1x_1.o lzo1x_1o.o lzo1x_d.o +lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o lib-$(CONFIG_RPM) += rpm.o lib-$(CONFIG_TAR) += tar.o Index: archival/Config.in =================================================================== --- archival/Config.in (revision 26238) +++ archival/Config.in (revision 26239) @@ -165,6 +165,21 @@ gzip is used to compress files. It's probably the most widely used UNIX compression program. +config LZOP + bool "lzop" + default n + help + Lzop compression/decompresion. + +config LZOP_COMPR_HIGH + bool "lzop complession levels 7,8,9 (not very useful)" + default n + depends on LZOP + help + High levels (7,8,9) of lzop compression. These levels + are actually slower than gzip at equivalent compression ratios + and take up 3.2K of code. + config RPM2CPIO bool "rpm2cpio" default n Index: archival/lzo1x_1.c =================================================================== --- archival/lzo1x_1.c (revision 0) +++ archival/lzo1x_1.c (revision 26239) @@ -0,0 +1,35 @@ +/* LZO1X-1 compression + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996..2008 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + Markus F.X.J. Oberhumer + http://www.oberhumer.com/opensource/lzo/ + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "libbb.h" +#include "liblzo.h" + +#define D_BITS 14 +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) + +#define DO_COMPRESS lzo1x_1_compress + +#include "lzo1x_c.c" Index: archival/lzo1x_9x.c =================================================================== --- archival/lzo1x_9x.c (revision 0) +++ archival/lzo1x_9x.c (revision 26239) @@ -0,0 +1,920 @@ +/* lzo1x_9x.c -- implementation of the LZO1X-999 compression algorithm + + This file is part of the LZO real-time data compression library. + + Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + The LZO library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ +*/ +#include "libbb.h" + +/* The following is probably only safe on Intel-compatible processors ... */ +#define LZO_UNALIGNED_OK_2 +#define LZO_UNALIGNED_OK_4 + +#include "liblzo.h" + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) + +/*********************************************************************** +// +************************************************************************/ +#define SWD_N M4_MAX_OFFSET /* size of ring buffer */ +#define SWD_F 2048 /* upper limit for match length */ + +#define SWD_BEST_OFF (LZO_MAX3(M2_MAX_LEN, M3_MAX_LEN, M4_MAX_LEN) + 1) + +typedef struct { + int init; + + unsigned look; /* bytes in lookahead buffer */ + + unsigned m_len; + unsigned m_off; + + const uint8_t *bp; + const uint8_t *ip; + const uint8_t *in; + const uint8_t *in_end; + uint8_t *out; + + unsigned r1_lit; + +} lzo1x_999_t; + +#define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) + +/* lzo_swd.c -- sliding window dictionary */ + +/*********************************************************************** +// +************************************************************************/ +#define SWD_UINT_MAX USHRT_MAX + +#ifndef SWD_HSIZE +# define SWD_HSIZE 16384 +#endif +#ifndef SWD_MAX_CHAIN +# define SWD_MAX_CHAIN 2048 +#endif + +#define HEAD3(b, p) \ + ( ((0x9f5f * ((((b[p]<<5)^b[p+1])<<5) ^ b[p+2])) >> 5) & (SWD_HSIZE-1) ) + +#if defined(LZO_UNALIGNED_OK_2) +# define HEAD2(b,p) (* (uint16_t *) &(b[p])) +#else +# define HEAD2(b,p) (b[p] ^ ((unsigned)b[p+1]<<8)) +#endif +#define NIL2 SWD_UINT_MAX + +typedef struct lzo_swd { + /* public - "built-in" */ + + /* public - configuration */ + unsigned max_chain; + int use_best_off; + + /* public - output */ + unsigned m_len; + unsigned m_off; + unsigned look; + int b_char; +#if defined(SWD_BEST_OFF) + unsigned best_off[SWD_BEST_OFF]; +#endif + + /* semi public */ + lzo1x_999_t *c; + unsigned m_pos; +#if defined(SWD_BEST_OFF) + unsigned best_pos[SWD_BEST_OFF]; +#endif + + /* private */ + unsigned ip; /* input pointer (lookahead) */ + unsigned bp; /* buffer pointer */ + unsigned rp; /* remove pointer */ + + unsigned node_count; + unsigned first_rp; + + uint8_t b[SWD_N + SWD_F]; + uint8_t b_wrap[SWD_F]; /* must follow b */ + uint16_t head3[SWD_HSIZE]; + uint16_t succ3[SWD_N + SWD_F]; + uint16_t best3[SWD_N + SWD_F]; + uint16_t llen3[SWD_HSIZE]; +#ifdef HEAD2 + uint16_t head2[65536L]; +#endif +} lzo_swd_t, *lzo_swd_p; + +#define SIZEOF_LZO_SWD_T (sizeof(lzo_swd_t)) + + +/* Access macro for head3. + * head3[key] may be uninitialized, but then its value will never be used. + */ +#define s_get_head3(s,key) s->head3[key] + + +/*********************************************************************** +// +************************************************************************/ +#define B_SIZE (SWD_N + SWD_F) + +static int swd_init(lzo_swd_p s) +{ + /* defaults */ + s->node_count = SWD_N; + + memset(s->llen3, 0, sizeof(s->llen3[0]) * (unsigned)SWD_HSIZE); +#ifdef HEAD2 + memset(s->head2, 0xff, sizeof(s->head2[0]) * 65536L); + assert(s->head2[0] == NIL2); +#endif + + s->ip = 0; + s->bp = s->ip; + s->first_rp = s->ip; + + assert(s->ip + SWD_F <= B_SIZE); + s->look = (unsigned) (s->c->in_end - s->c->ip); + if (s->look > 0) { + if (s->look > SWD_F) + s->look = SWD_F; + memcpy(&s->b[s->ip],s->c->ip,s->look); + s->c->ip += s->look; + s->ip += s->look; + } + if (s->ip == B_SIZE) + s->ip = 0; + + s->rp = s->first_rp; + if (s->rp >= s->node_count) + s->rp -= s->node_count; + else + s->rp += B_SIZE - s->node_count; + + return LZO_E_OK; +} + +#define swd_pos2off(s,pos) \ + (s->bp > (pos) ? s->bp - (pos) : B_SIZE - ((pos) - s->bp)) + + +/*********************************************************************** +// +************************************************************************/ +static void swd_getbyte(lzo_swd_p s) +{ + int c; + + if ((c = getbyte(*(s->c))) < 0) { + if (s->look > 0) + --s->look; + } else { + s->b[s->ip] = c; + if (s->ip < SWD_F) + s->b_wrap[s->ip] = c; + } + if (++s->ip == B_SIZE) + s->ip = 0; + if (++s->bp == B_SIZE) + s->bp = 0; + if (++s->rp == B_SIZE) + s->rp = 0; +} + + +/*********************************************************************** +// remove node from lists +************************************************************************/ +static void swd_remove_node(lzo_swd_p s, unsigned node) +{ + if (s->node_count == 0) { + unsigned key; + + key = HEAD3(s->b,node); + assert(s->llen3[key] > 0); + --s->llen3[key]; + +#ifdef HEAD2 + key = HEAD2(s->b,node); + assert(s->head2[key] != NIL2); + if ((unsigned) s->head2[key] == node) + s->head2[key] = NIL2; +#endif + } else + --s->node_count; +} + + +/*********************************************************************** +// +************************************************************************/ +static void swd_accept(lzo_swd_p s, unsigned n) +{ + assert(n <= s->look); + + while (n--) { + unsigned key; + + swd_remove_node(s,s->rp); + + /* add bp into HEAD3 */ + key = HEAD3(s->b,s->bp); + s->succ3[s->bp] = s_get_head3(s,key); + s->head3[key] = s->bp; + s->best3[s->bp] = SWD_F + 1; + s->llen3[key]++; + assert(s->llen3[key] <= SWD_N); + +#ifdef HEAD2 + /* add bp into HEAD2 */ + key = HEAD2(s->b,s->bp); + s->head2[key] = s->bp; +#endif + + swd_getbyte(s); + } +} + + +/*********************************************************************** +// +************************************************************************/ +static void swd_search(lzo_swd_p s, unsigned node, unsigned cnt) +{ + const uint8_t *p1; + const uint8_t *p2; + const uint8_t *px; + unsigned m_len = s->m_len; + const uint8_t *b = s->b; + const uint8_t *bp = s->b + s->bp; + const uint8_t *bx = s->b + s->bp + s->look; + unsigned char scan_end1; + + assert(s->m_len > 0); + + scan_end1 = bp[m_len - 1]; + for ( ; cnt-- > 0; node = s->succ3[node]) { + p1 = bp; + p2 = b + node; + px = bx; + + assert(m_len < s->look); + + if (p2[m_len - 1] == scan_end1 && + p2[m_len] == p1[m_len] && + p2[0] == p1[0] && + p2[1] == p1[1]) { + unsigned i; + assert(lzo_memcmp(bp,&b[node],3) == 0); + + p1 += 2; p2 += 2; + do {} while (++p1 < px && *p1 == *++p2); + i = p1-bp; + + assert(lzo_memcmp(bp,&b[node],i) == 0); + +#if defined(SWD_BEST_OFF) + if (i < SWD_BEST_OFF) { + if (s->best_pos[i] == 0) + s->best_pos[i] = node + 1; + } +#endif + if (i > m_len) { + s->m_len = m_len = i; + s->m_pos = node; + if (m_len == s->look) + return; + if (m_len >= SWD_F) + return; + if (m_len > (unsigned) s->best3[node]) + return; + scan_end1 = bp[m_len - 1]; + } + } + } +} + + +/*********************************************************************** +// +************************************************************************/ +#ifdef HEAD2 + +static int swd_search2(lzo_swd_p s) +{ + unsigned key; + + assert(s->look >= 2); + assert(s->m_len > 0); + + key = s->head2[ HEAD2(s->b,s->bp) ]; + if (key == NIL2) + return 0; + assert(lzo_memcmp(&s->b[s->bp],&s->b[key],2) == 0); +#if defined(SWD_BEST_OFF) + if (s->best_pos[2] == 0) + s->best_pos[2] = key + 1; +#endif + + if (s->m_len < 2) { + s->m_len = 2; + s->m_pos = key; + } + return 1; +} + +#endif + + +/*********************************************************************** +// +************************************************************************/ +static void swd_findbest(lzo_swd_p s) +{ + unsigned key; + unsigned cnt, node; + unsigned len; + + assert(s->m_len > 0); + + /* get current head, add bp into HEAD3 */ + key = HEAD3(s->b,s->bp); + node = s->succ3[s->bp] = s_get_head3(s,key); + cnt = s->llen3[key]++; + assert(s->llen3[key] <= SWD_N + SWD_F); + if (cnt > s->max_chain) + cnt = s->max_chain; + s->head3[key] = s->bp; + + s->b_char = s->b[s->bp]; + len = s->m_len; + if (s->m_len >= s->look) { + if (s->look == 0) + s->b_char = -1; + s->m_off = 0; + s->best3[s->bp] = SWD_F + 1; + } else { +#ifdef HEAD2 + if (swd_search2(s)) +#endif + if (s->look >= 3) + swd_search(s,node,cnt); + if (s->m_len > len) + s->m_off = swd_pos2off(s,s->m_pos); + s->best3[s->bp] = s->m_len; + +#if defined(SWD_BEST_OFF) + if (s->use_best_off) { + int i; + for (i = 2; i < SWD_BEST_OFF; i++) + if (s->best_pos[i] > 0) + s->best_off[i] = swd_pos2off(s,s->best_pos[i]-1); + else + s->best_off[i] = 0; + } +#endif + } + + swd_remove_node(s,s->rp); + +#ifdef HEAD2 + /* add bp into HEAD2 */ + key = HEAD2(s->b,s->bp); + s->head2[key] = s->bp; +#endif +} + +#undef HEAD3 +#undef HEAD2 +#undef s_get_head3 + + +/*********************************************************************** +// +************************************************************************/ +static int init_match(lzo1x_999_t *c, lzo_swd_p s, uint32_t use_best_off) +{ + int r; + + assert(!c->init); + c->init = 1; + + s->c = c; + + r = swd_init(s); + if (r != 0) + return r; + + s->use_best_off = use_best_off; + return r; +} + + +/*********************************************************************** +// +************************************************************************/ +static int find_match(lzo1x_999_t *c, lzo_swd_p s, + unsigned this_len, unsigned skip) +{ + assert(c->init); + + if (skip > 0) { + assert(this_len >= skip); + swd_accept(s, this_len - skip); + } else { + assert(this_len <= 1); + } + + s->m_len = 1; + s->m_len = 1; +#ifdef SWD_BEST_OFF + if (s->use_best_off) + memset(s->best_pos,0,sizeof(s->best_pos)); +#endif + swd_findbest(s); + c->m_len = s->m_len; + c->m_off = s->m_off; + + swd_getbyte(s); + + if (s->b_char < 0) { + c->look = 0; + c->m_len = 0; + } else { + c->look = s->look + 1; + } + c->bp = c->ip - c->look; + + return LZO_E_OK; +} + +/* this is a public functions, but there is no prototype in a header file */ +static int lzo1x_999_compress_internal(const uint8_t *in , unsigned in_len, + uint8_t *out, unsigned *out_len, + void *wrkmem, + unsigned good_length, + unsigned max_lazy, + unsigned max_chain, + uint32_t use_best_off); + + +/*********************************************************************** +// +************************************************************************/ +static uint8_t *code_match(lzo1x_999_t *c, + uint8_t *op, unsigned m_len, unsigned m_off) +{ + assert(op > c->out); + if (m_len == 2) { + assert(m_off <= M1_MAX_OFFSET); + assert(c->r1_lit > 0); assert(c->r1_lit < 4); + m_off -= 1; + *op++ = M1_MARKER | ((m_off & 3) << 2); + *op++ = m_off >> 2; + } else if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) { + assert(m_len >= 3); + m_off -= 1; + *op++ = ((m_len - 1) << 5) | ((m_off & 7) << 2); + *op++ = m_off >> 3; + assert(op[-2] >= M2_MARKER); + } else if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && c->r1_lit >= 4) { + assert(m_len == 3); + assert(m_off > M2_MAX_OFFSET); + m_off -= 1 + M2_MAX_OFFSET; + *op++ = M1_MARKER | ((m_off & 3) << 2); + *op++ = m_off >> 2; + } else if (m_off <= M3_MAX_OFFSET) { + assert(m_len >= 3); + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = M3_MARKER | (m_len - 2); + else { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = m_len; + } + *op++ = m_off << 2; + *op++ = m_off >> 6; + } else { + unsigned k; + + assert(m_len >= 3); + assert(m_off > 0x4000); assert(m_off <= 0xbfff); + m_off -= 0x4000; + k = (m_off & 0x4000) >> 11; + if (m_len <= M4_MAX_LEN) + *op++ = M4_MARKER | k | (m_len - 2); + else { + m_len -= M4_MAX_LEN; + *op++ = M4_MARKER | k | 0; + while (m_len > 255) + { + m_len -= 255; + *op++ = 0; + } + assert(m_len > 0); + *op++ = m_len; + } + *op++ = m_off << 2; + *op++ = m_off >> 6; + } + + return op; +} + + +static uint8_t *STORE_RUN(lzo1x_999_t *c, uint8_t *op, + const uint8_t *ii, unsigned t) +{ + if (op == c->out && t <= 238) { + *op++ = 17 + t; + } else if (t <= 3) { + op[-2] |= t; + } else if (t <= 18) { + *op++ = t - 3; + } else { + unsigned tt = t - 18; + + *op++ = 0; + while (tt > 255) { + tt -= 255; + *op++ = 0; + } + assert(tt > 0); + *op++ = tt; + } + do *op++ = *ii++; while (--t > 0); + + return op; +} + + +static uint8_t *code_run(lzo1x_999_t *c, uint8_t *op, const uint8_t *ii, + unsigned lit) +{ + if (lit > 0) { + assert(m_len >= 2); + op = STORE_RUN(c,op,ii,lit); + } else { + assert(m_len >= 3); + } + c->r1_lit = lit; + + return op; +} + + +/*********************************************************************** +// +************************************************************************/ +static int len_of_coded_match(unsigned m_len, unsigned m_off, unsigned lit) +{ + int n = 4; + + if (m_len < 2) + return -1; + if (m_len == 2) + return (m_off <= M1_MAX_OFFSET && lit > 0 && lit < 4) ? 2 : -1; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + return 2; + if (m_len == M2_MIN_LEN && m_off <= MX_MAX_OFFSET && lit >= 4) + return 2; + if (m_off <= M3_MAX_OFFSET) { + if (m_len <= M3_MAX_LEN) + return 3; + m_len -= M3_MAX_LEN; + } else if (m_off <= M4_MAX_OFFSET) { + if (m_len <= M4_MAX_LEN) + return 3; + m_len -= M4_MAX_LEN; + } else + return -1; + while (m_len > 255) { + m_len -= 255; + n++; + } + return n; +} + + +static int min_gain(unsigned ahead, unsigned lit1, + unsigned lit2, int l1, int l2, int l3) +{ + int lazy_match_min_gain = 0; + + assert (ahead >= 1); + lazy_match_min_gain += ahead; + + if (lit1 <= 3) + lazy_match_min_gain += (lit2 <= 3) ? 0 : 2; + else if (lit1 <= 18) + lazy_match_min_gain += (lit2 <= 18) ? 0 : 1; + + lazy_match_min_gain += (l2 - l1) * 2; + if (l3 > 0) + lazy_match_min_gain -= (ahead - l3) * 2; + + if (lazy_match_min_gain < 0) + lazy_match_min_gain = 0; + + return lazy_match_min_gain; +} + + +/*********************************************************************** +// +************************************************************************/ +#if defined(SWD_BEST_OFF) + +static void better_match(const lzo_swd_p swd, + unsigned *m_len, unsigned *m_off) +{ + + if (*m_len <= M2_MIN_LEN) + return; + + if (*m_off <= M2_MAX_OFFSET) + return; + + /* M3/M4 -> M2 */ + if (*m_off > M2_MAX_OFFSET && + *m_len >= M2_MIN_LEN + 1 && *m_len <= M2_MAX_LEN + 1 && + swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M2_MAX_OFFSET) + { + *m_len = *m_len - 1; + *m_off = swd->best_off[*m_len]; + return; + } + + /* M4 -> M2 */ + if (*m_off > M3_MAX_OFFSET && + *m_len >= M4_MAX_LEN + 1 && *m_len <= M2_MAX_LEN + 2 && + swd->best_off[*m_len-2] && swd->best_off[*m_len-2] <= M2_MAX_OFFSET) + { + *m_len = *m_len - 2; + *m_off = swd->best_off[*m_len]; + return; + } + /* M4 -> M3 */ + if (*m_off > M3_MAX_OFFSET && + *m_len >= M4_MAX_LEN + 1 && *m_len <= M3_MAX_LEN + 1 && + swd->best_off[*m_len-1] && swd->best_off[*m_len-1] <= M3_MAX_OFFSET) + { + *m_len = *m_len - 1; + *m_off = swd->best_off[*m_len]; + } +} + +#endif + + +/*********************************************************************** +// +************************************************************************/ +static int lzo1x_999_compress_internal(const uint8_t *in, unsigned in_len, + uint8_t *out, unsigned *out_len, + void *wrkmem, + unsigned good_length, + unsigned max_lazy, + unsigned max_chain, + uint32_t use_best_off) +{ + uint8_t *op; + const uint8_t *ii; + unsigned lit; + unsigned m_len, m_off; + lzo1x_999_t cc; + lzo1x_999_t * const c = &cc; + lzo_swd_p const swd = (lzo_swd_p) wrkmem; + int r; + + c->init = 0; + c->ip = c->in = in; + c->in_end = in + in_len; + c->out = out; + + op = out; + ii = c->ip; /* point to start of literal run */ + lit = 0; + c->r1_lit = 0; + + r = init_match(c, swd, use_best_off); + if (r != 0) + return r; + swd->max_chain = max_chain; + + r = find_match(c, swd, 0, 0); + if (r != 0) + return r; + + while (c->look > 0) { + unsigned ahead; + unsigned max_ahead; + int l1, l2, l3; + + m_len = c->m_len; + m_off = c->m_off; + + assert(c->bp == c->ip - c->look); + assert(c->bp >= in); + if (lit == 0) + ii = c->bp; + assert(ii + lit == c->bp); + assert(swd->b_char == *(c->bp)); + + if ( m_len < 2 || + (m_len == 2 && (m_off > M1_MAX_OFFSET || lit == 0 || lit >= 4)) || + /* Do not accept this match for compressed-data compatibility + * with LZO v1.01 and before + * [ might be a problem for decompress() and optimize() ] + */ + (m_len == 2 && op == out) || + (op == out && lit == 0)) + { + /* a literal */ + m_len = 0; + } + else if (m_len == M2_MIN_LEN) { + /* compression ratio improves if we code a literal in some cases */ + if (m_off > MX_MAX_OFFSET && lit >= 4) + m_len = 0; + } + + if (m_len == 0) { + /* a literal */ + lit++; + swd->max_chain = max_chain; + r = find_match(c,swd,1,0); + assert(r == 0); + continue; + } + + /* a match */ +#if defined(SWD_BEST_OFF) + if (swd->use_best_off) + better_match(swd,&m_len,&m_off); +#endif + + /* shall we try a lazy match ? */ + ahead = 0; + if (m_len >= max_lazy) { + /* no */ + l1 = 0; + max_ahead = 0; + } else { + /* yes, try a lazy match */ + l1 = len_of_coded_match(m_len,m_off,lit); + assert(l1 > 0); + max_ahead = LZO_MIN(2, (unsigned)l1 - 1); + } + + + while (ahead < max_ahead && c->look > m_len) { + int lazy_match_min_gain; + + if (m_len >= good_length) + swd->max_chain = max_chain >> 2; + else + swd->max_chain = max_chain; + r = find_match(c,swd,1,0); + ahead++; + + assert(r == 0); + assert(c->look > 0); + assert(ii + lit + ahead == c->bp); + + if (c->m_len < m_len) + continue; + if (c->m_len == m_len && c->m_off >= m_off) + continue; +#if defined(SWD_BEST_OFF) + if (swd->use_best_off) + better_match(swd,&c->m_len,&c->m_off); +#endif + l2 = len_of_coded_match(c->m_len,c->m_off,lit+ahead); + if (l2 < 0) + continue; + + /* compressed-data compatibility [see above] */ + l3 = (op == out) ? -1 : len_of_coded_match(ahead,m_off,lit); + + lazy_match_min_gain = min_gain(ahead,lit,lit+ahead,l1,l2,l3); + if (c->m_len >= m_len + lazy_match_min_gain) { + if (l3 > 0) { + /* code previous run */ + op = code_run(c,op,ii,lit); + lit = 0; + /* code shortened match */ + op = code_match(c,op,ahead,m_off); + } else { + lit += ahead; + assert(ii + lit == c->bp); + } + goto lazy_match_done; + } + } + + assert(ii + lit + ahead == c->bp); + + /* 1 - code run */ + op = code_run(c,op,ii,lit); + lit = 0; + + /* 2 - code match */ + op = code_match(c,op,m_len,m_off); + swd->max_chain = max_chain; + r = find_match(c,swd,m_len,1+ahead); + assert(r == 0); + + lazy_match_done: ; + } + + /* store final run */ + if (lit > 0) + op = STORE_RUN(c,op,ii,lit); + +#if defined(LZO_EOF_CODE) + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; +#endif + + *out_len = op - out; + + return LZO_E_OK; +} + + +/*********************************************************************** +// +************************************************************************/ +int lzo1x_999_compress_level(const uint8_t *in, unsigned in_len, + uint8_t *out, unsigned *out_len, + void *wrkmem, + int compression_level) +{ + static const struct { + uint16_t good_length; + uint16_t max_lazy; + uint16_t max_chain; + uint16_t use_best_off; + } c[3] = { + { 8, 32, 256, 0 }, + { 32, 128, 2048, 1 }, + { SWD_F, SWD_F, 4096, 1 } /* max. compression */ + }; + + if (compression_level < 7 || compression_level > 9) + return LZO_E_ERROR; + + compression_level -= 7; + return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem, + c[compression_level].good_length, + c[compression_level].max_lazy, + c[compression_level].max_chain, + c[compression_level].use_best_off); +} Index: include/usage.h =================================================================== --- include/usage.h (revision 26238) +++ include/usage.h (revision 26239) @@ -202,6 +202,31 @@ #define busybox_notes_usage \ "Hello world!\n" +#define lzop_trivial_usage \ + "[-cfvd123456789CF] [file..]" +#define lzop_full_usage "\n\n" \ + " -c Write to standard output" \ + "\n -f Force" \ + "\n -v Verbose" \ + "\n -d Decompress" \ + "\n -F Don't store or verify checksum" \ + "\n -C Also write checksum of compressed block" \ + "\n -1..9 Compression level" \ + +#define lzopcat_trivial_usage \ + "[-vCF] [file..]" +#define lzopcat_full_usage "\n\n" \ + " -v Verbose" \ + "\n -F Don't store or verify checksum" \ + +#define unlzop_trivial_usage \ + "[-cfvCF] [file..]" +#define unlzop_full_usage "\n\n" \ + " -c Write to standard output" \ + "\n -f Force" \ + "\n -v Verbose" \ + "\n -F Don't store or verify checksum" \ + #define bzcat_trivial_usage \ "FILE" #define bzcat_full_usage "\n\n" \ Index: include/applets.h =================================================================== --- include/applets.h (revision 26238) +++ include/applets.h (revision 26239) @@ -242,6 +242,8 @@ IF_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) IF_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) IF_UNLZMA(APPLET_ODDNAME(lzmacat, unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzmacat)) +IF_LZOP(APPLET(lzop, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzopcat)) IF_MAKEDEVS(APPLET(makedevs, _BB_DIR_SBIN, _BB_SUID_NEVER)) IF_MAKEMIME(APPLET(makemime, _BB_DIR_BIN, _BB_SUID_NEVER)) IF_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUID_NEVER)) @@ -401,6 +403,7 @@ IF_UNIQ(APPLET(uniq, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) IF_UNIX2DOS(APPLET_ODDNAME(unix2dos, dos2unix, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unix2dos)) IF_UNLZMA(APPLET(unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_LZOP(APPLET_ODDNAME(unlzop, lzop, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unlzop)) IF_UNZIP(APPLET(unzip, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) IF_UPTIME(APPLET(uptime, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) IF_USLEEP(APPLET_NOFORK(usleep, usleep, _BB_DIR_BIN, _BB_SUID_NEVER, usleep)) ------------------------------------------------------------------------ r26223 | vda | 2009-04-27 18:29:14 -0500 (Mon, 27 Apr 2009) | 17 lines Changed paths: M /trunk/busybox/shell/hush.c hush: make it possible to have interactive shell on non-ctty. init=/bin/hush: shows prompt, history works, etc. function old new delta hush_main 888 925 +37 block_signals 139 152 +13 builtin_fg_bg 284 293 +9 checkjobs_and_fg_shell 35 41 +6 sigexit 65 66 +1 reset_traps_to_defaults 165 164 -1 parse_stream 2200 2184 -16 run_list 2502 2475 -27 getpgid 35 - -35 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 5/3 up/down: 66/-79) Total: -13 bytes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26222) +++ shell/hush.c (revision 26223) @@ -417,15 +417,26 @@ /* "Globals" within this file */ /* Sorted roughly by size (smaller offsets == smaller code) */ struct globals { + /* interactive_fd != 0 means we are an interactive shell. + * If we are, then saved_tty_pgrp can also be != 0, meaning + * that controlling tty is available. With saved_tty_pgrp == 0, + * job control still works, but terminal signals + * (^C, ^Z, ^Y, ^\) won't work at all, and background + * process groups can only be created with "cmd &". + * With saved_tty_pgrp != 0, hush will use tcsetpgrp() + * to give tty to the foreground process group, + * and will take it back when the group is stopped (^Z) + * or killed (^C). + */ #if ENABLE_HUSH_INTERACTIVE /* 'interactive_fd' is a fd# open to ctty, if we have one * _AND_ if we decided to act interactively */ int interactive_fd; const char *PS1; const char *PS2; -#define G_interactive_fd (G.interactive_fd) +# define G_interactive_fd (G.interactive_fd) #else -#define G_interactive_fd 0 +# define G_interactive_fd 0 #endif #if ENABLE_FEATURE_EDITING line_input_t *line_input_state; @@ -434,10 +445,9 @@ pid_t last_bg_pid; #if ENABLE_HUSH_JOB int run_list_level; + int last_jobid; pid_t saved_tty_pgrp; - int last_jobid; struct pipe *job_list; - struct pipe *toplevel_list; #endif smallint flag_SIGINT; #if ENABLE_HUSH_LOOPS @@ -446,7 +456,7 @@ #if ENABLE_HUSH_FUNCTIONS /* 0: outside of a function (or sourced file) * -1: inside of a function, ok to use return builtin - * 1: return is invoked, skip all till end of func. + * 1: return is invoked, skip all till end of func */ smallint flag_return_in_progress; #endif @@ -1089,12 +1099,16 @@ */ enum { SPECIAL_INTERACTIVE_SIGS = 0 + | (1 << SIGTERM) + | (1 << SIGINT) + | (1 << SIGHUP) + , #if ENABLE_HUSH_JOB - | (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP) - | (1 << SIGHUP) + SPECIAL_JOB_SIGS = 0 + | (1 << SIGTTIN) + | (1 << SIGTTOU) + | (1 << SIGTSTP) #endif - | (1 << SIGTERM) - | (1 << SIGINT) }; //static void SIGCHLD_handler(int sig UNUSED_PARAM) @@ -1122,7 +1136,7 @@ /* Careful: we can end up here after [v]fork. Do not restore * tty pgrp then, only top-level shell process does that */ - if (G_interactive_fd && getpid() == G.root_pid) + if (G.saved_tty_pgrp && getpid() == G.root_pid) tcsetpgrp(G_interactive_fd, G.saved_tty_pgrp); /* Not a signal, just exit */ @@ -3131,7 +3145,7 @@ len += strlen(*argv) + 1; } while (*++argv); p = xmalloc(len); - pi->cmdtext = p;// = xmalloc(len); + pi->cmdtext = p; argv = pi->cmds[0].argv; do { len = strlen(*argv); @@ -3351,10 +3365,12 @@ { pid_t p; int rcode = checkjobs(fg_pipe); - /* Job finished, move the shell to the foreground */ - p = getpgid(0); /* pgid of our process */ - debug_printf_jobs("fg'ing ourself: getpgid(0)=%d\n", (int)p); - tcsetpgrp(G_interactive_fd, p); + if (G.saved_tty_pgrp) { + /* Job finished, move the shell to the foreground */ + p = getpgrp(); /* our process group id */ + debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p); + tcsetpgrp(G_interactive_fd, p); + } return rcode; } #endif @@ -3606,7 +3622,10 @@ pgrp = pi->pgrp; if (pgrp < 0) /* true for 1st process only */ pgrp = getpid(); - if (setpgid(0, pgrp) == 0 && pi->followup != PIPE_BG) { + if (setpgid(0, pgrp) == 0 + && pi->followup != PIPE_BG + && G.saved_tty_pgrp /* we have ctty */ + ) { /* We do it in *every* child, not just first, * to avoid races */ tcsetpgrp(G_interactive_fd, pgrp); @@ -4023,11 +4042,7 @@ check_and_run_traps(0); #if ENABLE_HUSH_JOB if (G.run_list_level == 1) -{ -debug_printf_exec("insert_bg_job1\n"); insert_bg_job(pi); -debug_printf_exec("insert_bg_job2\n"); -} #endif G.last_exitcode = rcode = EXIT_SUCCESS; debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); @@ -5896,8 +5911,11 @@ unsigned mask; mask = (1 << SIGQUIT); - if (G_interactive_fd) + if (G_interactive_fd) { mask = (1 << SIGQUIT) | SPECIAL_INTERACTIVE_SIGS; + if (G.saved_tty_pgrp) /* we have ctty, job control sigs work */ + mask |= SPECIAL_JOB_SIGS; + } G.non_DFL_mask = mask; if (!second_time) @@ -6179,52 +6197,55 @@ if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { G.saved_tty_pgrp = tcgetpgrp(STDIN_FILENO); debug_printf("saved_tty_pgrp:%d\n", G.saved_tty_pgrp); -//TODO: "interactive" and "have job control" are two different things. -//If tcgetpgrp fails here, "have job control" is false, but "interactive" -//should stay on! Currently, we mix these into one. - if (G.saved_tty_pgrp >= 0) { - /* try to dup stdin to high fd#, >= 255 */ - G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255); + if (G.saved_tty_pgrp < 0) + G.saved_tty_pgrp = 0; + + /* try to dup stdin to high fd#, >= 255 */ + G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255); + if (G_interactive_fd < 0) { + /* try to dup to any fd */ + G_interactive_fd = dup(STDIN_FILENO); if (G_interactive_fd < 0) { - /* try to dup to any fd */ - G_interactive_fd = dup(STDIN_FILENO); - if (G_interactive_fd < 0) - /* give up */ - G_interactive_fd = 0; + /* give up */ + G_interactive_fd = 0; + G.saved_tty_pgrp = 0; } + } // TODO: track & disallow any attempts of user -// to (inadvertently) close/redirect it - } +// to (inadvertently) close/redirect G_interactive_fd } debug_printf("interactive_fd:%d\n", G_interactive_fd); if (G_interactive_fd) { - pid_t shell_pgrp; + close_on_exec_on(G_interactive_fd); - /* We are indeed interactive shell, and we will perform - * job control. Setting up for that. */ + if (G.saved_tty_pgrp) { + /* If we were run as 'hush &', sleep until we are + * in the foreground (tty pgrp == our pgrp). + * If we get started under a job aware app (like bash), + * make sure we are now in charge so we don't fight over + * who gets the foreground */ + while (1) { + pid_t shell_pgrp = getpgrp(); + G.saved_tty_pgrp = tcgetpgrp(G_interactive_fd); + if (G.saved_tty_pgrp == shell_pgrp) + break; + /* send TTIN to ourself (should stop us) */ + kill(- shell_pgrp, SIGTTIN); + } + } - close_on_exec_on(G_interactive_fd); - /* If we were run as 'hush &', sleep until we are - * in the foreground (tty pgrp == our pgrp). - * If we get started under a job aware app (like bash), - * make sure we are now in charge so we don't fight over - * who gets the foreground */ - while (1) { - shell_pgrp = getpgrp(); - G.saved_tty_pgrp = tcgetpgrp(G_interactive_fd); - if (G.saved_tty_pgrp == shell_pgrp) - break; - /* send TTIN to ourself (should stop us) */ - kill(- shell_pgrp, SIGTTIN); - } /* Block some signals */ block_signals(signal_mask_is_inited); - /* Set other signals to restore saved_tty_pgrp */ - set_fatal_handlers(); - /* Put ourselves in our own process group */ - bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */ - /* Grab control of the terminal */ - tcsetpgrp(G_interactive_fd, getpid()); + + if (G.saved_tty_pgrp) { + /* Set other signals to restore saved_tty_pgrp */ + set_fatal_handlers(); + /* Put ourselves in our own process group + * (bash, too, does this only if ctty is available) */ + bb_setpgrp(); /* is the same as setpgid(our_pid, our_pid); */ + /* Grab control of the terminal */ + tcsetpgrp(G_interactive_fd, getpid()); + } /* -1 is special - makes xfuncs longjmp, not exit * (we reset die_sleep = 0 whereever we [v]fork) */ enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ @@ -6604,6 +6625,7 @@ if (!G_interactive_fd) return EXIT_FAILURE; + /* If they gave us no args, assume they want the last backgrounded task */ if (!argv[1]) { for (pi = G.job_list; pi; pi = pi->next) { @@ -6628,7 +6650,7 @@ found: /* TODO: bash prints a string representation * of job being foregrounded (like "sleep 1 | cat") */ - if (argv[0][0] == 'f') { + if (argv[0][0] == 'f' && G.saved_tty_pgrp) { /* Put the job into the foreground. */ tcsetpgrp(G_interactive_fd, pi->pgrp); } ------------------------------------------------------------------------ r26216 | vda | 2009-04-26 18:25:36 -0500 (Sun, 26 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush_test/hush-z_slow/leak_var2.tests make leak test more robust by unsetting all vars ------------------------------------------------------------------------ Index: shell/hush_test/hush-z_slow/leak_var2.tests =================================================================== --- shell/hush_test/hush-z_slow/leak_var2.tests (revision 26215) +++ shell/hush_test/hush-z_slow/leak_var2.tests (revision 26216) @@ -1,7 +1,6 @@ +echo "Warm up" t=1 export t - -echo "Warm up" i=1 while test $i != X; do t=111111111111111111111111111111111111111111111111111111111111111111111110$i @@ -14,10 +13,13 @@ if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi done +unset t i memleak echo "Measuring memory leak..." +t=1 +export t i=1 while test $i != X; do t=111111111111111111111111111111111111111111111111111111111111111111111110$i @@ -30,6 +32,7 @@ if test $i = 1111111111111111111111111111111111111111111113; then i=4; fi if test $i = 1111111111111111111111111111111111111111111114; then i=X; fi done +unset t i memleak kb=$? ------------------------------------------------------------------------ r26215 | vda | 2009-04-26 18:22:40 -0500 (Sun, 26 Apr 2009) | 9 lines Changed paths: M /trunk/busybox/libbb/getopt32.c M /trunk/busybox/shell/hush.c M /trunk/busybox/shell/hush_test/hush-vars/unset.right hush: make getopt32 usable in builtins. use it in unset. more uses are expected in the future. function old new delta getopt32 1356 1393 +37 builtin_export 256 266 +10 builtin_unset 418 380 -38 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26214) +++ shell/hush.c (revision 26215) @@ -6451,7 +6451,11 @@ } #if ENABLE_HUSH_EXPORT_N - opt_unexport = getopt32(argv, "+n"); /* "+": stop at 1st non-option */ + /* "!": do not abort on errors */ + /* "+": stop at 1st non-option */ + opt_unexport = getopt32(argv, "!+n"); + if (opt_unexport == (unsigned)-1) + return EXIT_FAILURE; argv += optind; #else opt_unexport = 0; @@ -6918,36 +6922,22 @@ static int builtin_unset(char **argv) { int ret; - char var; - char *arg; + unsigned opts; - if (!*++argv) - return EXIT_SUCCESS; - - var = 0; - while ((arg = *argv) != NULL && arg[0] == '-') { - arg++; - do { - switch (*arg) { - case 'v': - case 'f': - if (var == 0 || var == *arg) { - var = *arg; - break; - } - /* else: unset -vf, which is illegal. - * fall through */ - default: - bb_error_msg("unset: %s: invalid option", *argv); - return EXIT_FAILURE; - } - } while (*++arg); - argv++; + /* "!": do not abort on errors */ + /* "+": stop at 1st non-option */ + opts = getopt32(argv, "!+vf"); + if (opts == (unsigned)-1) + return EXIT_FAILURE; + if (opts == 3) { + bb_error_msg("unset: -v and -f are exclusive"); + return EXIT_FAILURE; } + argv += optind; ret = EXIT_SUCCESS; while (*argv) { - if (var != 'f') { + if (!(opts & 2)) { /* not -f */ if (unset_local_var(*argv)) { /* unset doesn't fail. * Error is when one tries to unset RO var. Index: shell/hush_test/hush-vars/unset.right =================================================================== --- shell/hush_test/hush-vars/unset.right (revision 26214) +++ shell/hush_test/hush-vars/unset.right (revision 26215) @@ -1,7 +1,6 @@ -hush: unset: -: invalid option +0 +unset: invalid option -- m 1 -hush: unset: -m: invalid option -1 0 ___ 0 f g Index: libbb/getopt32.c =================================================================== --- libbb/getopt32.c (revision 26214) +++ libbb/getopt32.c (revision 26215) @@ -72,6 +72,9 @@ env -i ls -d / Here we want env to process just the '-i', not the '-d'. + "!" Report bad option, missing required options, + inconsistent options with all-ones return value (instead of abort). + const char *applet_long_options This struct allows you to define long options: @@ -327,6 +330,7 @@ unsigned flags = 0; unsigned requires = 0; t_complementary complementary[33]; /* last stays zero-filled */ + char first_char; int c; const unsigned char *s; t_complementary *on_off; @@ -357,6 +361,11 @@ on_off = complementary; memset(on_off, 0, sizeof(complementary)); + /* skip bbox extension */ + first_char = applet_opts[0]; + if (first_char == '!') + applet_opts++; + /* skip GNU extension */ s = (const unsigned char *)applet_opts; if (*s == '+' || *s == '-') @@ -549,11 +558,11 @@ * is always NULL (see above) */ if (on_off->opt_char == '\0' /* && c != '\0' */) { /* c is probably '?' - "bad option" */ - bb_show_usage(); + goto error; } } if (flags & on_off->incongruously) - bb_show_usage(); + goto error; trigger = on_off->switch_on & on_off->switch_off; flags &= ~(on_off->switch_off ^ trigger); flags |= on_off->switch_on ^ trigger; @@ -577,16 +586,24 @@ /* check depending requires for given options */ for (on_off = complementary; on_off->opt_char; on_off++) { - if (on_off->requires && (flags & on_off->switch_on) && - (flags & on_off->requires) == 0) - bb_show_usage(); + if (on_off->requires + && (flags & on_off->switch_on) + && (flags & on_off->requires) == 0 + ) { + goto error; + } } if (requires && (flags & requires) == 0) - bb_show_usage(); + goto error; argc -= optind; if (argc < min_arg || (max_arg >= 0 && argc > max_arg)) - bb_show_usage(); + goto error; option_mask32 = flags; return flags; + + error: + if (first_char != '!') + bb_show_usage(); + return (int32_t)-1; } ------------------------------------------------------------------------ r26211 | vda | 2009-04-26 15:06:14 -0500 (Sun, 26 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c A /trunk/busybox/shell/hush_test/hush-misc/func4.right A /trunk/busybox/shell/hush_test/hush-misc/func4.tests M /trunk/busybox/shell/hush_test/hush-z_slow/leak_all1.tests hush: nommu fix for function passing ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26210) +++ shell/hush.c (revision 26211) @@ -5328,9 +5328,12 @@ * within double quotes by preceding it with a backslash. */ if (strchr("$`\"\\", next) != NULL) { - o_addqchr(dest, i_getch(input)); + ch = i_getch(input); + o_addqchr(dest, ch); + nommu_addchr(as_string, ch); } else { o_addqchr(dest, '\\'); + nommu_addchr(as_string, '\\'); } goto again; } Index: shell/hush_test/hush-misc/func4.right =================================================================== --- shell/hush_test/hush-misc/func4.right (revision 0) +++ shell/hush_test/hush-misc/func4.right (revision 26211) @@ -0,0 +1,2 @@ +24 +Done Index: shell/hush_test/hush-misc/func4.tests =================================================================== --- shell/hush_test/hush-misc/func4.tests (revision 0) +++ shell/hush_test/hush-misc/func4.tests (revision 26211) @@ -0,0 +1,7 @@ +func() { + eval "echo \"\${val_${1}}\"" +} + +val_x=24 +(func x) +echo Done Property changes on: shell/hush_test/hush-misc/func4.tests ___________________________________________________________________ Name: svn:executable + * Index: shell/hush_test/hush-z_slow/leak_all1.tests =================================================================== --- shell/hush_test/hush-z_slow/leak_all1.tests (revision 26210) +++ shell/hush_test/hush-z_slow/leak_all1.tests (revision 26211) @@ -67,6 +67,7 @@ f >/dev/null : $((i++)) done +unset i l t unset -f f memleak @@ -134,6 +135,7 @@ f >/dev/null : $((i++)) done +unset i l t unset -f f ------------------------------------------------------------------------ r26210 | vda | 2009-04-26 06:25:19 -0500 (Sun, 26 Apr 2009) | 6 lines Changed paths: M /trunk/busybox/shell/hush.c M /trunk/busybox/shell/hush_test/hush-arith/arith.right M /trunk/busybox/shell/hush_test/hush-vars/var_posix1.right M /trunk/busybox/shell/hush_test/hush-vars/var_posix1.tests M /trunk/busybox/shell/match.c M /trunk/busybox/shell/match.h hush: fix SEGV in % expansion function old new delta expand_variables 2203 2217 +14 ------------------------------------------------------------------------ Index: shell/match.h =================================================================== --- shell/match.h (revision 26209) +++ shell/match.h (revision 26210) @@ -2,12 +2,12 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -typedef char *(*scan_t)(char *string, char *match, bool zero); +typedef char *(*scan_t)(char *string, char *match, bool match_at_left); -char *scanleft(char *string, char *match, bool zero); -char *scanright(char *string, char *match, bool zero); +char *scanleft(char *string, char *match, bool match_at_left); +char *scanright(char *string, char *match, bool match_at_left); -static inline scan_t pick_scan(char op1, char op2, bool *zero) +static inline scan_t pick_scan(char op1, char op2, bool *match_at_left) { /* # - scanleft * ## - scanright @@ -15,10 +15,10 @@ * %% - scanleft */ if (op1 == '#') { - *zero = true; + *match_at_left = true; return op1 == op2 ? scanright : scanleft; } else { - *zero = false; + *match_at_left = false; return op1 == op2 ? scanleft : scanright; } } Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26209) +++ shell/hush.c (revision 26210) @@ -1990,12 +1990,9 @@ * (expansion of right-hand side of assignment == 1-element expand. * It will also do no globbing, and thus we must not backslash-quote!) */ - char first_ch, ored_ch; - int i; - const char *val; - char *dyn_val, *p; + char ored_ch; + char *p; - dyn_val = NULL; ored_ch = 0; debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg); @@ -2004,6 +2001,10 @@ debug_print_list("expand_vars_to_list[0]", output, n); while ((p = strchr(arg, SPECIAL_VAR_SYMBOL)) != NULL) { + char first_ch; + int i; + char *dyn_val = NULL; + const char *val = NULL; #if ENABLE_HUSH_TICK o_string subst_result = NULL_O_STRING; #endif @@ -2021,7 +2022,6 @@ if ((first_ch & 0x7f) != '@') ored_ch |= first_ch; - val = NULL; switch (first_ch & 0x7f) { /* Highest bit in first_ch indicates that var is double-quoted */ case '$': /* pid */ @@ -2194,16 +2194,16 @@ if (exp_op == '%' || exp_op == '#') { if (val) { /* we need to do a pattern match */ - bool zero; + bool match_at_left; char *loc; - scan_t scan = pick_scan(exp_op, *exp_word, &zero); + scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); if (exp_op == *exp_word) /* ## or %% */ ++exp_word; val = dyn_val = xstrdup(val); - loc = scan(dyn_val, exp_word, zero); - if (zero) + loc = scan(dyn_val, exp_word, match_at_left); + if (match_at_left) /* # or ## */ val = loc; - else + else if (loc) /* % or %% and match was found */ *loc = '\0'; } } else { @@ -2263,11 +2263,11 @@ } } /* default: */ } /* switch (char after ) */ + if (val) { o_addQstr(output, val, strlen(val)); } free(dyn_val); - dyn_val = NULL; /* Do the check to avoid writing to a const string */ if (*p != SPECIAL_VAR_SYMBOL) *p = SPECIAL_VAR_SYMBOL; Index: shell/hush_test/hush-vars/var_posix1.right =================================================================== --- shell/hush_test/hush-vars/var_posix1.right (revision 26209) +++ shell/hush_test/hush-vars/var_posix1.right (revision 26210) @@ -32,4 +32,5 @@ ababcdcd Empty: ababcdcd}_tail +ababcdcd end Index: shell/hush_test/hush-vars/var_posix1.tests =================================================================== --- shell/hush_test/hush-vars/var_posix1.tests (revision 26209) +++ shell/hush_test/hush-vars/var_posix1.tests (revision 26210) @@ -43,5 +43,6 @@ echo Empty:${var%%*} echo ${var#}}_tail # UNFIXED BUG: echo ${var#\}}_tail +echo ${var%\\*} echo end Index: shell/hush_test/hush-arith/arith.right =================================================================== --- shell/hush_test/hush-arith/arith.right (revision 26209) +++ shell/hush_test/hush-arith/arith.right (revision 26210) @@ -63,9 +63,9 @@ 40 40 hush: error in arithmetic hush: divide by 0 -hush: can't exec 'let': No such file or directory +hush: can't execute 'let': No such file or directory hush: error in arithmetic -hush: can't exec 'let': No such file or directory +hush: can't execute 'let': No such file or directory abc def ghi @@ -135,4 +135,4 @@ 42 42 42 -hush: can't exec 'a[b[c]d]=e': No such file or directory +hush: can't execute 'a[b[c]d]=e': No such file or directory Index: shell/match.c =================================================================== --- shell/match.c (revision 26209) +++ shell/match.c (revision 26210) @@ -11,8 +11,6 @@ * Kenneth Almquist. * * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. - * - * Original BSD copyright notice is retained at the end of this file. */ #ifdef STANDALONE # include @@ -28,7 +26,7 @@ #define pmatch(a, b) !fnmatch((a), (b), 0) -char *scanleft(char *string, char *pattern, bool zero) +char *scanleft(char *string, char *pattern, bool match_at_left) { char c; char *loc = string; @@ -38,7 +36,7 @@ const char *s; c = *loc; - if (zero) { + if (match_at_left) { *loc = '\0'; s = string; } else @@ -55,7 +53,7 @@ return NULL; } -char *scanright(char *string, char *pattern, bool zero) +char *scanright(char *string, char *pattern, bool match_at_left) { char c; char *loc = string + strlen(string); @@ -65,7 +63,7 @@ const char *s; c = *loc; - if (zero) { + if (match_at_left) { *loc = '\0'; s = string; } else @@ -88,7 +86,7 @@ char *string; char *op; char *pattern; - bool zero; + bool match_at_left; char *loc; int i; @@ -117,15 +115,15 @@ continue; } op = string + off; - scan = pick_scan(op[0], op[1], &zero); + scan = pick_scan(op[0], op[1], &match_at_left); pattern = op + 1; if (op[0] == op[1]) op[1] = '\0', ++pattern; op[0] = '\0'; - loc = scan(string, pattern, zero); + loc = scan(string, pattern, match_at_left); - if (zero) { + if (match_at_left) { printf("'%s'\n", loc); } else { *loc = '\0'; ------------------------------------------------------------------------ r26209 | vda | 2009-04-25 20:43:36 -0500 (Sat, 25 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/ifplugd.c ifplugd: tiny shrink ------------------------------------------------------------------------ Index: networking/ifplugd.c =================================================================== --- networking/ifplugd.c (revision 26208) +++ networking/ifplugd.c (revision 26209) @@ -222,7 +222,7 @@ static void set_ifreq_to_ifname(struct ifreq *ifreq) { memset(ifreq, 0, sizeof(struct ifreq)); - strncpy(ifreq->ifr_name, G.iface, IFNAMSIZ); + strncpy_IFNAMSIZ(ifreq->ifr_name, G.iface); } static const char *strstatus(int status) @@ -389,7 +389,7 @@ uint8_t mac[ETH_ALEN]; memset(&iwrequest, 0, sizeof(struct iwreq)); - strncpy(iwrequest.ifr_ifrn.ifrn_name, G.iface, IFNAMSIZ); + strncpy_IFNAMSIZ(iwrequest.ifr_ifrn.ifrn_name, G.iface); if (network_ioctl(SIOCGIWAP, &iwrequest) < 0) { bb_perror_msg("SIOCGIWAP failed"); ------------------------------------------------------------------------ r26208 | vda | 2009-04-25 20:17:44 -0500 (Sat, 25 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/ifplugd.c ifplugd: add copyright ------------------------------------------------------------------------ Index: networking/ifplugd.c =================================================================== --- networking/ifplugd.c (revision 26207) +++ networking/ifplugd.c (revision 26208) @@ -2,7 +2,7 @@ /* * ifplugd for busybox * - * Copyright (C) 2009 + * Copyright (C) 2009 Maksym Kryzhanovskyy * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ @@ -19,6 +19,21 @@ #define __user #include +/* +TODO: describe compat status here. + +One questionable point of the design is netlink usage: + +We have 1 second timeout by default to poll the link status, +it is short enough so that there are no real benefits in +using netlink to get "instantaneous" interface creation/deletion +notifications. We can check for interface existence by just +doing some fast ioctl using its name. + +Netlink code then can be just dropped (1k or more?) +*/ + + #define IFPLUGD_ENV_PREVIOUS "IFPLUGD_PREVIOUS" #define IFPLUGD_ENV_CURRENT "IFPLUGD_CURRENT" ------------------------------------------------------------------------ r26207 | vda | 2009-04-25 20:08:51 -0500 (Sat, 25 Apr 2009) | 4 lines Changed paths: M /trunk/busybox/include/applets.h M /trunk/busybox/include/usage.h M /trunk/busybox/networking/Config.in M /trunk/busybox/networking/Kbuild A /trunk/busybox/networking/ifplugd.c ifplugd: new applet by Maksym Kryzhanovskyy (xmaks AT email.cz) +3k code and 0.5k in messages. Most of the bloat due to compat :( ------------------------------------------------------------------------ Index: networking/Kbuild =================================================================== --- networking/Kbuild (revision 26206) +++ networking/Kbuild (revision 26207) @@ -18,6 +18,7 @@ lib-$(CONFIG_HTTPD) += httpd.o lib-$(CONFIG_IFCONFIG) += ifconfig.o interface.o lib-$(CONFIG_IFENSLAVE) += ifenslave.o interface.o +lib-$(CONFIG_IFPLUGD) += ifplugd.o lib-$(CONFIG_IFUPDOWN) += ifupdown.o lib-$(CONFIG_INETD) += inetd.o lib-$(CONFIG_IP) += ip.o Index: networking/ifplugd.c =================================================================== --- networking/ifplugd.c (revision 0) +++ networking/ifplugd.c (revision 26207) @@ -0,0 +1,810 @@ +/* vi: set sw=4 ts=4: */ +/* + * ifplugd for busybox + * + * Copyright (C) 2009 + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ +#include "libbb.h" + +#include +#include +#include +#include +#include +#include +#include + +#define __user +#include + +#define IFPLUGD_ENV_PREVIOUS "IFPLUGD_PREVIOUS" +#define IFPLUGD_ENV_CURRENT "IFPLUGD_CURRENT" + +enum { + FLAG_NO_AUTO = 1 << 0, // -a, Do not enable interface automatically + FLAG_NO_DAEMON = 1 << 1, // -n, Do not daemonize + FLAG_NO_SYSLOG = 1 << 2, // -s, Do not use syslog, use stderr instead + FLAG_IGNORE_FAIL = 1 << 3, // -f, Ignore detection failure, retry instead (failure is treated as DOWN) + FLAG_IGNORE_FAIL_POSITIVE = 1 << 4, // -F, Ignore detection failure, retry instead (failure is treated as UP) + FLAG_IFACE = 1 << 5, // -i, Specify ethernet interface + FLAG_RUN = 1 << 6, // -r, Specify program to execute + FLAG_IGNORE_RETVAL = 1 << 7, // -I, Don't exit on nonzero return value of program executed + FLAG_POLL_TIME = 1 << 8, // -t, Specify poll time in seconds + FLAG_DELAY_UP = 1 << 9, // -u, Specify delay for configuring interface + FLAG_DELAY_DOWN = 1 << 10, // -d, Specify delay for deconfiguring interface + FLAG_API_MODE = 1 << 11, // -m, Force API mode (mii, priv, ethtool, wlan, auto) + FLAG_NO_STARTUP = 1 << 12, // -p, Don't run script on daemon startup + FLAG_NO_SHUTDOWN = 1 << 13, // -q, Don't run script on daemon quit + FLAG_INITIAL_DOWN = 1 << 14, // -l, Run "down" script on startup if no cable is detected + FLAG_EXTRA_ARG = 1 << 15, // -x, Specify an extra argument for action script + FLAG_MONITOR = 1 << 16, // -M, Use interface monitoring +#if ENABLE_FEATURE_PIDFILE + FLAG_KILL = 1 << 17, // -k, Kill a running daemon +#endif +}; +#if ENABLE_FEATURE_PIDFILE +# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:Mk" +#else +# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M" +#endif + +enum { // api mode + API_AUTO = 'a', + API_ETHTOOL = 'e', + API_MII = 'm', + API_PRIVATE = 'p', + API_WLAN = 'w', + API_IFF = 'i', +}; + +enum { // interface status + IFSTATUS_ERR = -1, + IFSTATUS_DOWN = 0, + IFSTATUS_UP = 1, +}; + +enum { // constant fds + ioctl_fd = 3, + netlink_fd = 4, +}; + +struct globals { + smallint iface_last_status; + smallint iface_exists; + + /* Used in getopt32, must have sizeof == sizeof(int) */ + unsigned poll_time; + unsigned delay_up; + unsigned delay_down; + + const char *iface; + const char *api_mode; + const char *script_name; + const char *extra_arg; + + smallint (*detect_link_func)(void); + smallint (*cached_detect_link_func)(void); +}; +#define G (*ptr_to_globals) +#define INIT_G() do { \ + SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ + G.iface_last_status = -1; \ + G.iface_exists = 1; \ + G.poll_time = 1; \ + G.delay_down = 5; \ + G.iface = "eth0"; \ + G.api_mode = "a"; \ + G.script_name = "/etc/ifplugd/ifplugd.action"; \ +} while (0) + + +static int run_script(const char *action) +{ + pid_t pid; + int r; + + bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action); + +#if 1 + pid = vfork(); + if (pid < 0) { + bb_perror_msg("fork"); + return -1; + } + + if (pid == 0) { + /* child */ + execlp(G.script_name, G.script_name, G.iface, action, G.extra_arg, NULL); + bb_perror_msg_and_die("can't execute '%s'", G.script_name); + } + + /* parent */ + wait(&r); + r = WEXITSTATUS(r); + + bb_error_msg("exit code: %u", r); + return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r; + +#else /* insanity */ + + struct fd_pair pipe_pair; + char buf[256]; + int i = 0; + + xpiped_pair(pipe_pair); + + pid = vfork(); + if (pid < 0) { + bb_perror_msg("fork"); + return -1; + } + + /* child */ + if (pid == 0) { + xmove_fd(pipe_pair.wr, 1); + xdup2(1, 2); + if (pipe_pair.rd > 2) + close(pipe_pair.rd); + + // umask(0022); // Set up a sane umask + + execlp(G.script_name, G.script_name, G.iface, action, G.extra_arg, NULL); + _exit(EXIT_FAILURE); + } + + /* parent */ + close(pipe_pair.wr); + + while (1) { + if (bb_got_signal && bb_got_signal != SIGCHLD) { + bb_error_msg("killing child"); + kill(pid, SIGTERM); + bb_got_signal = 0; + break; + } + + r = read(pipe_pair.rd, &buf[i], 1); + + if (buf[i] == '\n' || i == sizeof(buf)-2 || r != 1) { + if (r == 1 && buf[i] != '\n') + i++; + + buf[i] = '\0'; + + if (i > 0) + bb_error_msg("client: %s", buf); + + i = 0; + } else { + i++; + } + + if (r != 1) + break; + } + + close(pipe_pair.rd); + + wait(&r); + + if (!WIFEXITED(r) || WEXITSTATUS(r) != 0) { + bb_error_msg("program execution failed, return value is %i", + WEXITSTATUS(r)); + return option_mask32 & FLAG_IGNORE_RETVAL ? 0 : WEXITSTATUS(r); + } + bb_error_msg("program executed successfully"); + return 0; +#endif +} + +static int network_ioctl(int request, void* data) +{ + return ioctl(ioctl_fd, request, data); +} + +static void set_ifreq_to_ifname(struct ifreq *ifreq) +{ + memset(ifreq, 0, sizeof(struct ifreq)); + strncpy(ifreq->ifr_name, G.iface, IFNAMSIZ); +} + +static const char *strstatus(int status) +{ + if (status == IFSTATUS_ERR) + return "error"; + return "down\0up" + (status * 5); +} + +static void up_iface(void) +{ + struct ifreq ifrequest; + + if (!G.iface_exists) + return; + + set_ifreq_to_ifname(&ifrequest); + if (network_ioctl(SIOCGIFFLAGS, &ifrequest) < 0) { + bb_perror_msg("can't %cet interface flags", 'g'); + G.iface_exists = 0; + return; + } + + if (!(ifrequest.ifr_flags & IFF_UP)) { + ifrequest.ifr_flags |= IFF_UP; + /* Let user know we mess up with interface */ + bb_error_msg("upping interface"); + if (network_ioctl(SIOCSIFFLAGS, &ifrequest) < 0) + bb_perror_msg_and_die("can't %cet interface flags", 's'); + } + +#if 0 /* why do we mess with IP addr? It's not our business */ + if (network_ioctl(SIOCGIFADDR, &ifrequest) < 0) { + bb_error_msg("can't get interface address"); + } else if (ifrequest.ifr_addr.sa_family != AF_INET) { + bb_perror_msg("The interface is not IP-based"); + } else { + ((struct sockaddr_in*)(&ifrequest.ifr_addr))->sin_addr.s_addr = INADDR_ANY; + if (network_ioctl(SIOCSIFADDR, &ifrequest) < 0) + bb_perror_msg("can't set interface address"); + } + if (network_ioctl(SIOCGIFFLAGS, &ifrequest) < 0) { + bb_perror_msg("can't get interface flags"); + return; + } +#endif +} + +static void maybe_up_new_iface(void) +{ + if (!(option_mask32 & FLAG_NO_AUTO)) + up_iface(); + +#if 0 /* bloat */ + struct ifreq ifrequest; + struct ethtool_drvinfo driver_info; + + set_ifreq_to_ifname(&ifrequest); + driver_info.cmd = ETHTOOL_GDRVINFO; + ifrequest.ifr_data = &driver_info; + if (network_ioctl(SIOCETHTOOL, &ifrequest) == 0) { + char buf[sizeof("/xx:xx:xx:xx:xx:xx")]; + + /* Get MAC */ + buf[0] = '\0'; + set_ifreq_to_ifname(&ifrequest); + if (network_ioctl(SIOCGIFHWADDR, &ifrequest) == 0) { + sprintf(buf, "/%02X:%02X:%02X:%02X:%02X:%02X", + (uint8_t)(ifrequest.ifr_hwaddr.sa_data[0]), + (uint8_t)(ifrequest.ifr_hwaddr.sa_data[1]), + (uint8_t)(ifrequest.ifr_hwaddr.sa_data[2]), + (uint8_t)(ifrequest.ifr_hwaddr.sa_data[3]), + (uint8_t)(ifrequest.ifr_hwaddr.sa_data[4]), + (uint8_t)(ifrequest.ifr_hwaddr.sa_data[5])); + } + + bb_error_msg("Using interface %s%s with driver<%s> (version: %s)", + G.iface, buf, driver_info.driver, driver_info.version); + } +#endif + + G.cached_detect_link_func = NULL; +} + +static smallint detect_link_mii(void) +{ + struct ifreq ifreq; + + set_ifreq_to_ifname(&ifreq); + + if (network_ioctl(SIOCGMIIPHY, &ifreq) < 0) { + bb_perror_msg("SIOCGMIIPHY failed"); + return IFSTATUS_ERR; + } + + ((unsigned short*)&ifreq.ifr_data)[1] = 1; + + if (network_ioctl(SIOCGMIIREG, &ifreq) < 0) { + bb_perror_msg("SIOCGMIIREG failed"); + return IFSTATUS_ERR; + } + + return (((unsigned short*)&ifreq.ifr_data)[3] & 0x0004) ? + IFSTATUS_UP : IFSTATUS_DOWN; +} + +static smallint detect_link_priv(void) +{ + struct ifreq ifreq; + + set_ifreq_to_ifname(&ifreq); + + if (network_ioctl(SIOCDEVPRIVATE, &ifreq) < 0) { + bb_perror_msg("SIOCDEVPRIVATE failed"); + return IFSTATUS_ERR; + } + + ((unsigned short*) &ifreq.ifr_data)[1] = 1; + + if (network_ioctl(SIOCDEVPRIVATE+1, &ifreq) < 0) { + bb_perror_msg("SIOCDEVPRIVATE+1 failed"); + return IFSTATUS_ERR; + } + + return (((unsigned short*)&ifreq.ifr_data)[3] & 0x0004) ? + IFSTATUS_UP : IFSTATUS_DOWN; +} + +static smallint detect_link_ethtool(void) +{ + struct ifreq ifreq; + struct ethtool_value edata; + + set_ifreq_to_ifname(&ifreq); + + edata.cmd = ETHTOOL_GLINK; + ifreq.ifr_data = &edata; + + if (network_ioctl(SIOCETHTOOL, &ifreq) < 0) { + bb_perror_msg("ETHTOOL_GLINK failed"); + return IFSTATUS_ERR; + } + + return edata.data ? IFSTATUS_UP : IFSTATUS_DOWN; +} + +static smallint detect_link_iff(void) +{ + struct ifreq ifreq; + + set_ifreq_to_ifname(&ifreq); + + if (network_ioctl(SIOCGIFFLAGS, &ifreq) < 0) { + bb_perror_msg("SIOCGIFFLAGS failed"); + return IFSTATUS_ERR; + } + + return (ifreq.ifr_flags & IFF_RUNNING) ? IFSTATUS_UP : IFSTATUS_DOWN; +} + +static smallint detect_link_wlan(void) +{ + struct iwreq iwrequest; + uint8_t mac[ETH_ALEN]; + + memset(&iwrequest, 0, sizeof(struct iwreq)); + strncpy(iwrequest.ifr_ifrn.ifrn_name, G.iface, IFNAMSIZ); + + if (network_ioctl(SIOCGIWAP, &iwrequest) < 0) { + bb_perror_msg("SIOCGIWAP failed"); + return IFSTATUS_ERR; + } + + memcpy(mac, &(iwrequest.u.ap_addr.sa_data), ETH_ALEN); + + if (mac[0] == 0xFF || mac[0] == 0x44 || mac[0] == 0x00) { + for (int i = 1; i < ETH_ALEN; ++i) { + if (mac[i] != mac[0]) + return IFSTATUS_UP; + } + return IFSTATUS_DOWN; + } + + return IFSTATUS_UP; +} + +static smallint detect_link_auto(void) +{ + const char *method; + smallint iface_status; + smallint sv_logmode; + + if (G.cached_detect_link_func) { + iface_status = G.cached_detect_link_func(); + if (iface_status != IFSTATUS_ERR) + return iface_status; + } + + sv_logmode = logmode; + logmode = LOGMODE_NONE; + + iface_status = detect_link_ethtool(); + if (iface_status != IFSTATUS_ERR) { + G.cached_detect_link_func = detect_link_ethtool; + method = "SIOCETHTOOL"; + found_method: + logmode = sv_logmode; + bb_error_msg("using %s detection mode", method); + return iface_status; + } + + iface_status = detect_link_mii(); + if (iface_status != IFSTATUS_ERR) { + G.cached_detect_link_func = detect_link_mii; + method = "SIOCGMIIPHY"; + goto found_method; + } + + iface_status = detect_link_priv(); + if (iface_status != IFSTATUS_ERR) { + G.cached_detect_link_func = detect_link_priv; + method = "SIOCDEVPRIVATE"; + goto found_method; + } + + iface_status = detect_link_wlan(); + if (iface_status != IFSTATUS_ERR) { + G.cached_detect_link_func = detect_link_wlan; + method = "wireless extension"; + goto found_method; + } + + iface_status = detect_link_iff(); + if (iface_status != IFSTATUS_ERR) { + G.cached_detect_link_func = detect_link_iff; + method = "IFF_RUNNING"; + goto found_method; + } + + logmode = sv_logmode; + return iface_status; /* IFSTATUS_ERR */ +} + +static smallint detect_link(void) +{ + smallint status; + + if (!G.iface_exists) + return (option_mask32 & FLAG_MONITOR) ? IFSTATUS_DOWN : IFSTATUS_ERR; + +#if 0 +/* Why? This behavior makes it hard to temporary down the iface. + * It makes a bit more sense to do only in maybe_up_new_iface. + * OTOH, maybe detect_link_wlan needs this. Then it should be done + * _only_ there. + */ + if (!(option_mask32 & FLAG_NO_AUTO)) + up_iface(); +#endif + + status = G.detect_link_func(); + if (status == IFSTATUS_ERR) { + if (option_mask32 & FLAG_IGNORE_FAIL) + status = IFSTATUS_DOWN; + if (option_mask32 & FLAG_IGNORE_FAIL_POSITIVE) + status = IFSTATUS_UP; + } + + if (status == IFSTATUS_ERR + && G.detect_link_func == detect_link_auto + ) { + bb_error_msg("failed to detect link status"); + } + + if (status != G.iface_last_status) { +//TODO: is it safe to repeatedly do this? + setenv(IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_last_status), 1); + setenv(IFPLUGD_ENV_CURRENT, strstatus(status), 1); + G.iface_last_status = status; + } + + return status; +} + +static NOINLINE int check_existence_through_netlink(void) +{ + char replybuf[1024]; + + while (1) { + struct nlmsghdr *mhdr; + ssize_t bytes; + + bytes = recv(netlink_fd, &replybuf, sizeof(replybuf), MSG_DONTWAIT); + if (bytes < 0) { + if (errno == EAGAIN) + return G.iface_exists; + if (errno == EINTR) + continue; + + bb_perror_msg("netlink: recv"); + return -1; + } + + mhdr = (struct nlmsghdr*)replybuf; + while (bytes > 0) { + if (!NLMSG_OK(mhdr, bytes) + || bytes < sizeof(struct nlmsghdr) + || bytes < mhdr->nlmsg_len + ) { + bb_error_msg("netlink packet too small or truncated"); + return -1; + } + + if (mhdr->nlmsg_type == RTM_NEWLINK || mhdr->nlmsg_type == RTM_DELLINK) { + struct rtattr *attr; + struct ifinfomsg *imsg; + int attr_len; + + imsg = NLMSG_DATA(mhdr); + + if (mhdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) { + bb_error_msg("netlink packet too small or truncated"); + return -1; + } + + attr = (struct rtattr*)((char*)imsg + NLMSG_ALIGN(sizeof(struct ifinfomsg))); + attr_len = NLMSG_PAYLOAD(mhdr, sizeof(struct ifinfomsg)); + + while (RTA_OK(attr, attr_len)) { + if (attr->rta_type == IFLA_IFNAME) { + char ifname[IFNAMSIZ + 1]; + int len = RTA_PAYLOAD(attr); + + if (len > IFNAMSIZ) + len = IFNAMSIZ; + memcpy(ifname, RTA_DATA(attr), len); + if (strcmp(G.iface, ifname) == 0) { + G.iface_exists = (mhdr->nlmsg_type == RTM_NEWLINK); + } + } + attr = RTA_NEXT(attr, attr_len); + } + } + + mhdr = NLMSG_NEXT(mhdr, bytes); + } + } + + return G.iface_exists; +} + +static NOINLINE int netlink_open(void) +{ + int fd; + struct sockaddr_nl addr; + + fd = xsocket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); + + memset(&addr, 0, sizeof(addr)); + addr.nl_family = AF_NETLINK; + addr.nl_groups = RTMGRP_LINK; + addr.nl_pid = getpid(); + + xbind(fd, (struct sockaddr*)&addr, sizeof(addr)); + + return fd; +} + +static NOINLINE pid_t read_pid(const char *filename) +{ + int len; + char buf[128]; + + len = open_read_close(filename, buf, 127); + if (len > 0) { + buf[len] = '\0'; + /* returns ULONG_MAX on error => -1 */ + return bb_strtoul(buf, NULL, 10); + } + return 0; +} + +int ifplugd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int ifplugd_main(int argc UNUSED_PARAM, char **argv) +{ + int iface_status; + int delay_time; + const char *iface_status_str; + struct pollfd netlink_pollfd[1]; + unsigned opts; +#if ENABLE_FEATURE_PIDFILE + char *pidfile_name; + pid_t pid_from_pidfile; +#endif + + INIT_G(); + + opt_complementary = "t+:u+:d+"; + opts = getopt32(argv, OPTION_STR, + &G.iface, &G.script_name, &G.poll_time, &G.delay_up, + &G.delay_down, &G.api_mode, &G.extra_arg); + + applet_name = xasprintf("ifplugd(%s)", G.iface); + +#if ENABLE_FEATURE_PIDFILE + pidfile_name = xasprintf(_PATH_VARRUN"ifplugd.%s.pid", G.iface); + pid_from_pidfile = read_pid(pidfile_name); + + if (opts & FLAG_KILL) { + if (pid_from_pidfile > 0) + kill(pid_from_pidfile, SIGQUIT); + return EXIT_SUCCESS; + } + + if (pid_from_pidfile > 0 && kill(pid_from_pidfile, 0) == 0) + bb_error_msg_and_die("daemon already running"); +#endif + + switch (G.api_mode[0]) { + case API_AUTO: + G.detect_link_func = detect_link_auto; + break; + case API_ETHTOOL: + G.detect_link_func = detect_link_ethtool; + break; + case API_MII: + G.detect_link_func = detect_link_mii; + break; + case API_PRIVATE: + G.detect_link_func = detect_link_priv; + break; + case API_WLAN: + G.detect_link_func = detect_link_wlan; + break; + case API_IFF: + G.detect_link_func = detect_link_iff; + break; + default: + bb_error_msg_and_die("unknown API mode '%s'", G.api_mode); + } + + if (!(opts & FLAG_NO_DAEMON)) + bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); + + xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), ioctl_fd); + if (opts & FLAG_MONITOR) { + xmove_fd(netlink_open(), netlink_fd); + } + + write_pidfile(pidfile_name); + + /* this can't be moved before socket creation */ + if (!(opts & FLAG_NO_SYSLOG)) { + openlog(applet_name, 0, LOG_DAEMON); + logmode |= LOGMODE_SYSLOG; + } + + bb_signals(0 + | (1 << SIGINT ) + | (1 << SIGTERM) + | (1 << SIGQUIT) + | (1 << SIGHUP ) /* why we ignore it? */ + /* | (1 << SIGCHLD) - run_script does not use it anymore */ + , record_signo); + + bb_error_msg("started: %s", bb_banner); + + if (opts & FLAG_MONITOR) { + struct ifreq ifrequest; + set_ifreq_to_ifname(&ifrequest); + G.iface_exists = (network_ioctl(SIOCGIFINDEX, &ifrequest) == 0); + } + + if (G.iface_exists) + maybe_up_new_iface(); + + iface_status = detect_link(); + if (iface_status == IFSTATUS_ERR) + goto exiting; + iface_status_str = strstatus(iface_status); + + if (opts & FLAG_MONITOR) { + bb_error_msg("interface %s", + G.iface_exists ? "exists" + : "doesn't exist, waiting"); + } + /* else we assume it always exists, but don't mislead user + * by potentially lying that it really exists */ + + if (G.iface_exists) { + bb_error_msg("link is %s", iface_status_str); + } + + if ((!(opts & FLAG_NO_STARTUP) + && iface_status == IFSTATUS_UP + ) + || (opts & FLAG_INITIAL_DOWN) + ) { + if (run_script(iface_status_str) != 0) + goto exiting; + } + + /* Main loop */ + netlink_pollfd[0].fd = netlink_fd; + netlink_pollfd[0].events = POLLIN; + delay_time = 0; + while (1) { + int iface_status_old; + int iface_exists_old; + + switch (bb_got_signal) { + case SIGINT: + case SIGTERM: + bb_got_signal = 0; + goto cleanup; + case SIGQUIT: + bb_got_signal = 0; + goto exiting; + default: + bb_got_signal = 0; + break; + } + + if (poll(netlink_pollfd, + (opts & FLAG_MONITOR) ? 1 : 0, + G.poll_time * 1000 + ) < 0 + ) { + if (errno == EINTR) + continue; + bb_perror_msg("poll"); + goto exiting; + } + + iface_status_old = iface_status; + iface_exists_old = G.iface_exists; + + if ((opts & FLAG_MONITOR) + && (netlink_pollfd[0].revents & POLLIN) + ) { + G.iface_exists = check_existence_through_netlink(); + if (G.iface_exists < 0) /* error */ + goto exiting; + if (iface_exists_old != G.iface_exists) { + bb_error_msg("interface %sappeared", + G.iface_exists ? "" : "dis"); + if (G.iface_exists) + maybe_up_new_iface(); + } + } + + /* note: if !G.iface_exists, returns DOWN */ + iface_status = detect_link(); + if (iface_status == IFSTATUS_ERR) { + if (!(opts & FLAG_MONITOR)) + goto exiting; + iface_status = IFSTATUS_DOWN; + } + iface_status_str = strstatus(iface_status); + + if (iface_status_old != iface_status) { + bb_error_msg("link is %s", iface_status_str); + + if (delay_time) { + /* link restored its old status before + * we run script. don't run the script: */ + delay_time = 0; + } else { + delay_time = monotonic_sec(); + if (iface_status == IFSTATUS_UP) + delay_time += G.delay_up; + if (iface_status == IFSTATUS_DOWN) + delay_time += G.delay_down; + if (delay_time == 0) + delay_time++; + } + } + + if (delay_time && (int)(monotonic_sec() - delay_time) >= 0) { + delay_time = 0; + if (run_script(iface_status_str) != 0) + goto exiting; + } + } /* while (1) */ + + cleanup: + if (!(opts & FLAG_NO_SHUTDOWN) + && (iface_status == IFSTATUS_UP + || (iface_status == IFSTATUS_DOWN && delay_time) + ) + ) { + setenv(IFPLUGD_ENV_PREVIOUS, strstatus(iface_status), 1); + setenv(IFPLUGD_ENV_CURRENT, strstatus(-1), 1); + run_script("down\0up"); /* reusing string */ + } + + exiting: + remove_pidfile(pidfile_name); + bb_error_msg_and_die("exiting"); +} Index: networking/Config.in =================================================================== --- networking/Config.in (revision 26206) +++ networking/Config.in (revision 26207) @@ -303,6 +303,12 @@ Userspace application to bind several interfaces to a logical interface (use with kernel bonding driver). +config IFPLUGD + bool "ifplugd" + default n + help + Network interface plug detection daemon. + config IFUPDOWN bool "ifupdown" default n Index: include/usage.h =================================================================== --- include/usage.h (revision 26206) +++ include/usage.h (revision 26207) @@ -1727,22 +1727,47 @@ /* "\n -r, --receive-slave Create a receive-only slave" */ #define ifenslave_example_usage \ - "To create a bond device, simply follow these three steps :\n" \ - "- ensure that the required drivers are properly loaded :\n" \ + "To create a bond device, simply follow these three steps:\n" \ + "- ensure that the required drivers are properly loaded:\n" \ " # modprobe bonding ; modprobe <3c59x|eepro100|pcnet32|tulip|...>\n" \ - "- assign an IP address to the bond device :\n" \ + "- assign an IP address to the bond device:\n" \ " # ifconfig bond0 netmask broadcast \n" \ - "- attach all the interfaces you need to the bond device :\n" \ + "- attach all the interfaces you need to the bond device:\n" \ " # ifenslave bond0 eth0 eth1 eth2\n" \ " If bond0 didn't have a MAC address, it will take eth0's. Then, all\n" \ " interfaces attached AFTER this assignment will get the same MAC addr.\n\n" \ - " To detach a dead interface without setting the bond device down :\n" \ - " # ifenslave -d bond0 eth1\n\n" \ - " To set the bond device down and automatically release all the slaves :\n" \ - " # ifconfig bond0 down\n\n" \ - " To change active slave :\n" \ - " # ifenslave -c bond0 eth0\n" \ + " To detach a dead interface without setting the bond device down:\n" \ + " # ifenslave -d bond0 eth1\n\n" \ + " To set the bond device down and automatically release all the slaves:\n" \ + " # ifconfig bond0 down\n\n" \ + " To change active slave:\n" \ + " # ifenslave -c bond0 eth0\n" \ +#define ifplugd_trivial_usage \ + "[options]" +#define ifplugd_full_usage "\n\n" \ + "Network interface plug detection daemon.\n\n" \ + "Options:\n" \ + "\n -n Do not daemonize" \ + "\n -s Do not log to syslog" \ + "\n -i IFACE Interface" \ + "\n -f/-F Treat link detection error as link down/link up" \ + "\n (otherwise exit on error)" \ + "\n -a Do not up interface automatically" \ + "\n -M Monitor creation/destruction of interface" \ + "\n (otherwise it must exist)" \ + "\n -r PROG Script to run" \ + "\n -x ARG Extra argument for script" \ + "\n -I Don't exit on nonzero exit code from script" \ + "\n -p Don't run script on daemon startup" \ + "\n -q Don't run script on daemon quit" \ + "\n -l Run script on startup even if no cable is detected" \ + "\n -t SECS Poll time in seconds" \ + "\n -u SECS Delay before running script after link up" \ + "\n -d SECS Delay after link down" \ + "\n -m MODE API mode (mii, priv, ethtool, wlan, auto)" \ + "\n -k Kill running daemon" \ + #define ifup_trivial_usage \ "[-ain"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] ifaces..." #define ifup_full_usage "\n\n" \ @@ -4346,17 +4371,17 @@ "CMD: {add|del|change|replace|show}\n" \ "\n" \ "qdisc [ handle QHANDLE ] [ root |"IF_FEATURE_TC_INGRESS(" ingress |")" parent CLASSID ]\n" \ - /* "\t[ estimator INTERVAL TIME_CONSTANT ]\n" */ \ - "\t[ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" \ - "\tQDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n" \ + /* "[ estimator INTERVAL TIME_CONSTANT ]\n" */ \ + " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" \ + " QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n" \ "qdisc show [ dev STRING ]"IF_FEATURE_TC_INGRESS(" [ingress]")"\n" \ "class [ classid CLASSID ] [ root | parent CLASSID ]\n" \ - "\t[ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" \ + " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" \ "class show [ dev STRING ] [ root | parent CLASSID ]\n" \ "filter [ pref PRIO ] [ protocol PROTO ]\n" \ /* "\t[ estimator INTERVAL TIME_CONSTANT ]\n" */ \ - "\t[ root | classid CLASSID ] [ handle FILTERID ]\n" \ - "\t[ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" \ + " [ root | classid CLASSID ] [ handle FILTERID ]\n" \ + " [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" \ "filter show [ dev STRING ] [ root | parent CLASSID ]" #define tcpsvd_trivial_usage \ Index: include/applets.h =================================================================== --- include/applets.h (revision 26206) +++ include/applets.h (revision 26207) @@ -189,6 +189,7 @@ IF_IFCONFIG(APPLET(ifconfig, _BB_DIR_SBIN, _BB_SUID_NEVER)) IF_IFUPDOWN(APPLET_ODDNAME(ifdown, ifupdown, _BB_DIR_SBIN, _BB_SUID_NEVER, ifdown)) IF_IFENSLAVE(APPLET(ifenslave, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_IFPLUGD(APPLET(ifplugd, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) IF_IFUPDOWN(APPLET_ODDNAME(ifup, ifupdown, _BB_DIR_SBIN, _BB_SUID_NEVER, ifup)) IF_INETD(APPLET(inetd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) IF_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_NEVER)) ------------------------------------------------------------------------ r26206 | vda | 2009-04-25 08:26:10 -0500 (Sat, 25 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/libbb/update_passwd.c shrink if FEATURE_SHADOWPASSWDS is off ------------------------------------------------------------------------ Index: libbb/update_passwd.c =================================================================== --- libbb/update_passwd.c (revision 26205) +++ libbb/update_passwd.c (revision 26206) @@ -100,7 +100,7 @@ name = xasprintf("%s:", name); user_len = strlen(name); - if (strstr(filename, "shadow")) + if (ENABLE_FEATURE_SHADOWPASSWDS && strstr(filename, "shadow")) old_fp = fopen(filename, "r+"); else old_fp = fopen_or_warn(filename, "r+"); ------------------------------------------------------------------------ r26205 | vda | 2009-04-25 08:16:53 -0500 (Sat, 25 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/libbb/xconnect.c M /trunk/busybox/networking/Config.in M /trunk/busybox/networking/nc.c M /trunk/busybox/networking/nc_bloaty.c add FEATURE_UNIX_LOCAL. By Ingo van Lil (inguin AT gmx.de) ------------------------------------------------------------------------ Index: networking/nc_bloaty.c =================================================================== --- networking/nc_bloaty.c (revision 26204) +++ networking/nc_bloaty.c (revision 26205) @@ -377,9 +377,7 @@ socklen_t x = sizeof(optbuf); rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); - if (rr < 0) - bb_perror_msg("getsockopt failed"); - else if (x) { /* we've got options, lessee em... */ + if (rr >= 0 && x) { /* we've got options, lessee em... */ bin2hex(bigbuf_net, optbuf, x); bigbuf_net[2*x] = '\0'; fprintf(stderr, "IP options: %s\n", bigbuf_net); @@ -603,7 +601,10 @@ mobygrams are kinda fun and exercise the reassembler. */ if (rr <= 0) { /* at end, or fukt, or ... */ FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ - close(0); + close(STDIN_FILENO); +// Does it make sense to shutdown(net_fd, SHUT_WR) +// to let other side know that we won't write anything anymore? +// (and what about keeping compat if we do that?) } else { rzleft = rr; zp = bigbuf_in; @@ -768,7 +769,12 @@ setsockopt_reuseaddr(netfd); if (o_udpmode) socket_want_pktinfo(netfd); - xbind(netfd, &ouraddr->u.sa, ouraddr->len); + if (!ENABLE_FEATURE_UNIX_LOCAL + || o_listen + || ouraddr->u.sa.sa_family != AF_UNIX + ) { + xbind(netfd, &ouraddr->u.sa, ouraddr->len); + } #if 0 setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); Index: networking/nc.c =================================================================== --- networking/nc.c (revision 26204) +++ networking/nc.c (revision 26205) @@ -34,7 +34,6 @@ IF_NOT_NC_EXTRA (const) unsigned delay = 0; IF_NOT_NC_EXTRA (const int execparam = 0;) IF_NC_EXTRA (char **execparam = NULL;) - len_and_sockaddr *lsa; fd_set readfds, testfds; int opt; /* must be signed (getopt returns -1) */ @@ -44,17 +43,17 @@ while ((opt = getopt(argc, argv, "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 ) { - if (ENABLE_NC_SERVER && opt=='l') + if (ENABLE_NC_SERVER && opt == 'l') IF_NC_SERVER(do_listen++); - else if (ENABLE_NC_SERVER && opt=='p') + else if (ENABLE_NC_SERVER && opt == 'p') IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); - else if (ENABLE_NC_EXTRA && opt=='w') + else if (ENABLE_NC_EXTRA && opt == 'w') IF_NC_EXTRA( wsecs = xatou(optarg)); - else if (ENABLE_NC_EXTRA && opt=='i') + else if (ENABLE_NC_EXTRA && opt == 'i') IF_NC_EXTRA( delay = xatou(optarg)); - else if (ENABLE_NC_EXTRA && opt=='f') + else if (ENABLE_NC_EXTRA && opt == 'f') IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); - else if (ENABLE_NC_EXTRA && opt=='e' && optind <= argc) { + else if (ENABLE_NC_EXTRA && opt == 'e' && optind <= argc) { /* We cannot just 'break'. We should let getopt finish. ** Or else we won't be able to find where ** 'host' and 'port' params are @@ -80,9 +79,12 @@ argc -= optind; // -l and -f don't mix if (do_listen && cfd) bb_show_usage(); - // Listen or file modes need zero arguments, client mode needs 2 - if (do_listen || cfd) { + // File mode needs need zero arguments, listen mode needs zero or one, + // client mode needs one or two + if (cfd) { if (argc) bb_show_usage(); + } else if (do_listen) { + if (argc > 1) bb_show_usage(); } else { if (!argc || argc > 2) bb_show_usage(); } @@ -99,24 +101,20 @@ if (!cfd) { if (do_listen) { - /* create_and_bind_stream_or_die(NULL, lport) - * would've work wonderfully, but we need - * to know lsa */ - sfd = xsocket_stream(&lsa); - if (lport) - set_nport(lsa, htons(lport)); - setsockopt_reuseaddr(sfd); - xbind(sfd, &lsa->u.sa, lsa->len); + sfd = create_and_bind_stream_or_die(argv[0], lport); xlisten(sfd, do_listen); /* can be > 1 */ +#if 0 /* nc-1.10 does not do this (without -v) */ /* If we didn't specify a port number, * query and print it after listen() */ if (!lport) { - getsockname(sfd, &lsa->u.sa, &lsa->len); - lport = get_nport(&lsa->u.sa); + len_and_sockaddr lsa; + lsa.len = LSA_SIZEOF_SA; + getsockname(sfd, &lsa.u.sa, &lsa.len); + lport = get_nport(&lsa.u.sa); fdprintf(2, "%d\n", ntohs(lport)); } +#endif close_on_exec_on(sfd); - free(lsa); accept_again: cfd = accept(sfd, NULL, 0); if (cfd < 0) Index: networking/Config.in =================================================================== --- networking/Config.in (revision 26204) +++ networking/Config.in (revision 26205) @@ -12,6 +12,13 @@ Enable IPv6 support in busybox. This adds IPv6 support in the networking applets. +config FEATURE_UNIX_LOCAL + bool "Enable Unix domain socket support" + default n + help + Enable Unix domain socket support in all busybox networking + applets. + config FEATURE_PREFER_IPV4_ADDRESS bool "Prefer IPv4 addresses from DNS queries" default y Index: libbb/xconnect.c =================================================================== --- libbb/xconnect.c (revision 26204) +++ libbb/xconnect.c (revision 26205) @@ -9,6 +9,7 @@ #include #include +#include #include "libbb.h" void FAST_FUNC setsockopt_reuseaddr(int fd) @@ -160,13 +161,26 @@ int ai_flags) { int rc; - len_and_sockaddr *r = NULL; + len_and_sockaddr *r; struct addrinfo *result = NULL; struct addrinfo *used_res; const char *org_host = host; /* only for error msg */ const char *cp; struct addrinfo hint; + if (ENABLE_FEATURE_UNIX_LOCAL && strncmp(host, "local:", 6) == 0) { + struct sockaddr_un *sun; + + r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_un)); + r->len = sizeof(struct sockaddr_un); + r->u.sa.sa_family = AF_UNIX; + sun = (struct sockaddr_un *)&r->u.sa; + safe_strncpy(sun->sun_path, host + 6, sizeof(sun->sun_path)); + return r; + } + + r = NULL; + /* Ugly parsing of host:addr */ if (ENABLE_FEATURE_IPV6 && host[0] == '[') { /* Even uglier parsing of [xx]:nn */ @@ -188,6 +202,7 @@ } if (cp) { /* points to ":" or "]:" */ int sz = cp - host + 1; + host = safe_strncpy(alloca(sz), host, sz); if (ENABLE_FEATURE_IPV6 && *cp != ':') { cp++; /* skip ']' */ @@ -371,6 +386,13 @@ int rc; socklen_t salen; + if (ENABLE_FEATURE_UNIX_LOCAL && sa->sa_family == AF_UNIX) { + struct sockaddr_un *sun = (struct sockaddr_un *)sa; + return xasprintf("local:%.*s", + (int) sizeof(sun->sun_path), + sun->sun_path); + } + salen = LSA_SIZEOF_SA; #if ENABLE_FEATURE_IPV6 if (sa->sa_family == AF_INET) ------------------------------------------------------------------------ r26204 | vda | 2009-04-25 07:19:35 -0500 (Sat, 25 Apr 2009) | 19 lines Changed paths: M /trunk/busybox/archival/Config.in M /trunk/busybox/archival/libunarchive/decompress_unlzma.c unlzma: speedup, by Pascal Bellard (pascal.bellard AT ads-lu.com) LZMA_FAST off: 10% faster and: function old new delta rc_is_bit_1 - 92 +92 rc_do_normalize 45 81 +36 rc_update_bit_1 25 - -25 rc_update_bit_0 30 - -30 rc_is_bit_0_helper 38 - -38 rc_get_bit 60 17 -43 rc_read 48 - -48 unpack_lzma_stream 1768 1517 -251 ------------------------------------------------------------------------------ (add/remove: 1/4 grow/shrink: 1/2 up/down: 128/-435) Total: -307 bytes LZMA_FAST on: 14% faster and: unpack_lzma_stream 2301 2737 +436 rc_get_bit 106 - -106 ------------------------------------------------------------------------ Index: archival/Config.in =================================================================== --- archival/Config.in (revision 26203) +++ archival/Config.in (revision 26204) @@ -283,8 +283,8 @@ default n depends on UNLZMA help - This option reduces decompression time by about 33% at the cost of - a 2K bigger binary. + This option reduces decompression time by about 25% at the cost of + a 1K bigger binary. config UNZIP bool "unzip" Index: archival/libunarchive/decompress_unlzma.c =================================================================== --- archival/libunarchive/decompress_unlzma.c (revision 26203) +++ archival/libunarchive/decompress_unlzma.c (revision 26204) @@ -8,14 +8,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ - #include "libbb.h" #include "unarchive.h" #if ENABLE_FEATURE_LZMA_FAST # define speed_inline ALWAYS_INLINE +# define size_inline #else # define speed_inline +# define size_inline ALWAYS_INLINE #endif @@ -44,8 +45,8 @@ #define RC_MODEL_TOTAL_BITS 11 -/* Called twice: once at startup and once in rc_normalize() */ -static void rc_read(rc_t *rc) +/* Called twice: once at startup (LZMA_FAST only) and once in rc_normalize() */ +static size_inline void rc_read(rc_t *rc) { int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE); if (buffer_size <= 0) @@ -54,8 +55,17 @@ rc->buffer_end = RC_BUFFER + buffer_size; } +/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */ +static void rc_do_normalize(rc_t *rc) +{ + if (rc->ptr >= rc->buffer_end) + rc_read(rc); + rc->range <<= 8; + rc->code = (rc->code << 8) | *rc->ptr++; +} + /* Called once */ -static rc_t* rc_init(int fd) /*, int buffer_size) */ +static ALWAYS_INLINE rc_t* rc_init(int fd) /*, int buffer_size) */ { int i; rc_t *rc; @@ -63,17 +73,18 @@ rc = xmalloc(sizeof(*rc) + RC_BUFFER_SIZE); rc->fd = fd; - /* rc->buffer_size = buffer_size; */ - rc->buffer_end = RC_BUFFER + RC_BUFFER_SIZE; rc->ptr = rc->buffer_end; - rc->code = 0; - rc->range = 0xFFFFFFFF; for (i = 0; i < 5; i++) { +#if ENABLE_FEATURE_LZMA_FAST if (rc->ptr >= rc->buffer_end) rc_read(rc); rc->code = (rc->code << 8) | *rc->ptr++; +#else + rc_do_normalize(rc); +#endif } + rc->range = 0xFFFFFFFF; return rc; } @@ -83,14 +94,6 @@ free(rc); } -/* Called twice, but one callsite is in speed_inline'd rc_is_bit_0_helper() */ -static void rc_do_normalize(rc_t *rc) -{ - if (rc->ptr >= rc->buffer_end) - rc_read(rc); - rc->range <<= 8; - rc->code = (rc->code << 8) | *rc->ptr++; -} static ALWAYS_INLINE void rc_normalize(rc_t *rc) { if (rc->range < (1 << RC_TOP_BITS)) { @@ -98,49 +101,28 @@ } } -/* rc_is_bit_0 is called 9 times */ -/* Why rc_is_bit_0_helper exists? - * Because we want to always expose (rc->code < rc->bound) to optimizer. - * Thus rc_is_bit_0 is always inlined, and rc_is_bit_0_helper is inlined - * only if we compile for speed. - */ -static speed_inline uint32_t rc_is_bit_0_helper(rc_t *rc, uint16_t *p) +/* rc_is_bit_1 is called 9 times */ +static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p) { rc_normalize(rc); rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS); - return rc->bound; -} -static ALWAYS_INLINE int rc_is_bit_0(rc_t *rc, uint16_t *p) -{ - uint32_t t = rc_is_bit_0_helper(rc, p); - return rc->code < t; -} - -/* Called ~10 times, but very small, thus inlined */ -static speed_inline void rc_update_bit_0(rc_t *rc, uint16_t *p) -{ - rc->range = rc->bound; - *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; -} -static speed_inline void rc_update_bit_1(rc_t *rc, uint16_t *p) -{ + if (rc->code < rc->bound) { + rc->range = rc->bound; + *p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS; + return 0; + } rc->range -= rc->bound; rc->code -= rc->bound; *p -= *p >> RC_MOVE_BITS; + return 1; } /* Called 4 times in unlzma loop */ -static int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol) +static speed_inline int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol) { - if (rc_is_bit_0(rc, p)) { - rc_update_bit_0(rc, p); - *symbol *= 2; - return 0; - } else { - rc_update_bit_1(rc, p); - *symbol = *symbol * 2 + 1; - return 1; - } + int ret = rc_is_bit_1(rc, p); + *symbol = *symbol * 2 + ret; + return ret; } /* Called once */ @@ -266,13 +248,13 @@ header.dst_size = SWAP_LE64(header.dst_size); if (header.dict_size == 0) - header.dict_size = 1; + header.dict_size++; buffer = xmalloc(MIN(header.dst_size, header.dict_size)); num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); p = xmalloc(num_probs * sizeof(*p)); - num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp)); + num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; for (i = 0; i < num_probs; i++) p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; @@ -282,9 +264,8 @@ int pos_state = (buffer_pos + global_pos) & pos_state_mask; prob = p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state; - if (rc_is_bit_0(rc, prob)) { + if (!rc_is_bit_1(rc, prob)) { mi = 1; - rc_update_bit_0(rc, prob); prob = (p + LZMA_LITERAL + (LZMA_LIT_SIZE * ((((buffer_pos + global_pos) & literal_pos_mask) << lc) + (previous_byte >> (8 - lc)) @@ -340,27 +321,21 @@ int offset; uint16_t *prob_len; - rc_update_bit_1(rc, prob); prob = p + LZMA_IS_REP + state; - if (rc_is_bit_0(rc, prob)) { - rc_update_bit_0(rc, prob); + if (!rc_is_bit_1(rc, prob)) { rep3 = rep2; rep2 = rep1; rep1 = rep0; state = state < LZMA_NUM_LIT_STATES ? 0 : 3; prob = p + LZMA_LEN_CODER; } else { - rc_update_bit_1(rc, prob); - prob = p + LZMA_IS_REP_G0 + state; - if (rc_is_bit_0(rc, prob)) { - rc_update_bit_0(rc, prob); + prob += LZMA_IS_REP_G0 - LZMA_IS_REP; + if (!rc_is_bit_1(rc, prob)) { prob = (p + LZMA_IS_REP_0_LONG + (state << LZMA_NUM_POS_BITS_MAX) + pos_state ); - if (rc_is_bit_0(rc, prob)) { - rc_update_bit_0(rc, prob); - + if (!rc_is_bit_1(rc, prob)) { state = state < LZMA_NUM_LIT_STATES ? 9 : 11; #if ENABLE_FEATURE_LZMA_FAST pos = buffer_pos - rep0; @@ -372,25 +347,16 @@ len = 1; goto string; #endif - } else { - rc_update_bit_1(rc, prob); } } else { uint32_t distance; - rc_update_bit_1(rc, prob); - prob = p + LZMA_IS_REP_G1 + state; - if (rc_is_bit_0(rc, prob)) { - rc_update_bit_0(rc, prob); - distance = rep1; - } else { - rc_update_bit_1(rc, prob); - prob = p + LZMA_IS_REP_G2 + state; - if (rc_is_bit_0(rc, prob)) { - rc_update_bit_0(rc, prob); - distance = rep2; - } else { - rc_update_bit_1(rc, prob); + prob += LZMA_IS_REP_G1 - LZMA_IS_REP_G0; + distance = rep1; + if (rc_is_bit_1(rc, prob)) { + prob += LZMA_IS_REP_G2 - LZMA_IS_REP_G1; + distance = rep2; + if (rc_is_bit_1(rc, prob)) { distance = rep3; rep3 = rep2; } @@ -404,24 +370,20 @@ } prob_len = prob + LZMA_LEN_CHOICE; - if (rc_is_bit_0(rc, prob_len)) { - rc_update_bit_0(rc, prob_len); - prob_len = (prob + LZMA_LEN_LOW - + (pos_state << LZMA_LEN_NUM_LOW_BITS)); + if (!rc_is_bit_1(rc, prob_len)) { + prob_len += LZMA_LEN_LOW - LZMA_LEN_CHOICE + + (pos_state << LZMA_LEN_NUM_LOW_BITS); offset = 0; num_bits = LZMA_LEN_NUM_LOW_BITS; } else { - rc_update_bit_1(rc, prob_len); - prob_len = prob + LZMA_LEN_CHOICE_2; - if (rc_is_bit_0(rc, prob_len)) { - rc_update_bit_0(rc, prob_len); - prob_len = (prob + LZMA_LEN_MID - + (pos_state << LZMA_LEN_NUM_MID_BITS)); + prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE; + if (!rc_is_bit_1(rc, prob_len)) { + prob_len += LZMA_LEN_MID - LZMA_LEN_CHOICE_2 + + (pos_state << LZMA_LEN_NUM_MID_BITS); offset = 1 << LZMA_LEN_NUM_LOW_BITS; num_bits = LZMA_LEN_NUM_MID_BITS; } else { - rc_update_bit_1(rc, prob_len); - prob_len = prob + LZMA_LEN_HIGH; + prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2; offset = ((1 << LZMA_LEN_NUM_LOW_BITS) + (1 << LZMA_LEN_NUM_MID_BITS)); num_bits = LZMA_LEN_NUM_HIGH_BITS; @@ -438,19 +400,20 @@ ((len < LZMA_NUM_LEN_TO_POS_STATES ? len : LZMA_NUM_LEN_TO_POS_STATES - 1) << LZMA_NUM_POS_SLOT_BITS); - rc_bit_tree_decode(rc, prob, LZMA_NUM_POS_SLOT_BITS, - &pos_slot); + rc_bit_tree_decode(rc, prob, + LZMA_NUM_POS_SLOT_BITS, &pos_slot); + rep0 = pos_slot; if (pos_slot >= LZMA_START_POS_MODEL_INDEX) { num_bits = (pos_slot >> 1) - 1; rep0 = 2 | (pos_slot & 1); + prob = p + LZMA_ALIGN; if (pos_slot < LZMA_END_POS_MODEL_INDEX) { rep0 <<= num_bits; - prob = p + LZMA_SPEC_POS + rep0 - pos_slot - 1; + prob += LZMA_SPEC_POS - LZMA_ALIGN - 1 + rep0 - pos_slot; } else { num_bits -= LZMA_NUM_ALIGN_BITS; while (num_bits--) rep0 = (rep0 << 1) | rc_direct_bit(rc); - prob = p + LZMA_ALIGN; rep0 <<= LZMA_NUM_ALIGN_BITS; num_bits = LZMA_NUM_ALIGN_BITS; } @@ -461,8 +424,7 @@ rep0 |= i; i <<= 1; } - } else - rep0 = pos_slot; + } if (++rep0 == 0) break; } ------------------------------------------------------------------------ r26203 | vapier | 2009-04-25 01:16:37 -0500 (Sat, 25 Apr 2009) | 1 line Changed paths: M /trunk/busybox/miscutils/watchdog.c we need to daemonize *before* opening the watchdog device ------------------------------------------------------------------------ Index: miscutils/watchdog.c =================================================================== --- miscutils/watchdog.c (revision 26202) +++ miscutils/watchdog.c (revision 26203) @@ -45,6 +45,15 @@ opt_complementary = "=1"; /* must have exactly 1 argument */ opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); + /* We need to daemonize *before* opening the watchdog as many drivers + * will only allow one process at a time to do so. Since daemonizing + * is not perfect (child may run before parent finishes exiting), we + * can't rely on parent exiting before us (let alone *cleanly* releasing + * the watchdog fd -- something else that may not even be allowed). + */ + if (!(opts & OPT_FOREGROUND)) + bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); + if (opts & OPT_HTIMER) htimer_duration = xatou_sfx(ht_arg, suffixes); stimer_duration = htimer_duration / 2; @@ -76,10 +85,6 @@ stimer_duration, htimer_duration * 1000); #endif - if (!(opts & OPT_FOREGROUND)) { - bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); - } - while (1) { /* * Make sure we clear the counter before sleeping, ------------------------------------------------------------------------ r26201 | vapier | 2009-04-24 01:40:30 -0500 (Fri, 24 Apr 2009) | 1 line Changed paths: M /trunk/busybox/shell/hush.c do not tell people they can enter "help" if help has actually been disabled ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26200) +++ shell/hush.c (revision 26201) @@ -6259,7 +6259,9 @@ if (!ENABLE_FEATURE_SH_EXTRA_QUIET && G_interactive_fd) { printf("\n\n%s hush - the humble shell\n", bb_banner); - printf("Enter 'help' for a list of built-in commands.\n\n"); + if (ENABLE_HUSH_HELP) + puts("Enter 'help' for a list of built-in commands."); + puts(""); } parse_and_run_file(stdin); ------------------------------------------------------------------------ r26200 | vapier | 2009-04-24 01:26:18 -0500 (Fri, 24 Apr 2009) | 1 line Changed paths: M /trunk/busybox/shell/hush.c use get_local_var_value() rather than getenv() when working with PS1/PS2/HOME, respect the PS2 env var, and make sure that the prompt changes whenever PS1/PS2 changes so we dont have to re-exec the shell to get a changed prompt ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26199) +++ shell/hush.c (revision 26200) @@ -795,6 +795,13 @@ #endif +#if ENABLE_HUSH_INTERACTIVE +static void cmdedit_update_prompt(void); +#else +# define cmdedit_update_prompt() +#endif + + /* Utility functions */ static int glob_needed(const char *s) @@ -1332,6 +1339,8 @@ exp: if (flg_export == 1) cur->flg_export = 1; + if (name_len == 4 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S') + cmdedit_update_prompt(); if (cur->flg_export) { if (flg_export == -1) { cur->flg_export = 0; @@ -1365,6 +1374,8 @@ prev->next = cur->next; debug_printf_env("%s: unsetenv '%s'\n", __func__, cur->varstr); bb_unsetenv(cur->varstr); + if (name_len == 3 && cur->varstr[0] == 'P' && cur->varstr[1] == 'S') + cmdedit_update_prompt(); if (!cur->max_len) free(cur->varstr); free(cur); @@ -1421,14 +1432,17 @@ #if ENABLE_HUSH_INTERACTIVE -static void cmdedit_set_initial_prompt(void) +static void cmdedit_update_prompt(void) { if (ENABLE_FEATURE_EDITING_FANCY_PROMPT) { - G.PS1 = getenv("PS1"); + G.PS1 = get_local_var_value("PS1"); if (G.PS1 == NULL) G.PS1 = "\\w \\$ "; + G.PS2 = get_local_var_value("PS2"); } else G.PS1 = NULL; + if (G.PS2 == NULL) + G.PS2 = "> "; } static const char* setup_prompt_string(int promptmode) @@ -6002,11 +6016,7 @@ G.global_argv = argv; /* Initialize some more globals to non-zero values */ set_cwd(); -#if ENABLE_HUSH_INTERACTIVE - if (ENABLE_FEATURE_EDITING) - cmdedit_set_initial_prompt(); - G.PS2 = "> "; -#endif + cmdedit_update_prompt(); if (setjmp(die_jmp)) { /* xfunc has failed! die die die */ @@ -6334,7 +6344,7 @@ * bash says "bash: cd: HOME not set" and does nothing * (exitcode 1) */ - newdir = getenv("HOME") ? : "/"; + newdir = get_local_var_value("HOME") ? : "/"; } if (chdir(newdir)) { /* Mimic bash message exactly */ ------------------------------------------------------------------------ r26188 | vda | 2009-04-22 18:25:48 -0500 (Wed, 22 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/inetd.c inetd: constify data ------------------------------------------------------------------------ Index: networking/inetd.c =================================================================== --- networking/inetd.c (revision 26187) +++ networking/inetd.c (revision 26188) @@ -658,7 +658,7 @@ } { - static int8_t SOCK_xxx[] ALIGN1 = { + static const int8_t SOCK_xxx[] ALIGN1 = { -1, SOCK_STREAM, SOCK_DGRAM, SOCK_RDM, SOCK_SEQPACKET, SOCK_RAW ------------------------------------------------------------------------ r26187 | vda | 2009-04-22 16:35:52 -0500 (Wed, 22 Apr 2009) | 13 lines Changed paths: M /trunk/busybox/include/usage.h M /trunk/busybox/loginutils/Config.in M /trunk/busybox/loginutils/addgroup.c M /trunk/busybox/loginutils/adduser.c adduser/addgroup: support specifying uid/gid, add system account creation mode. By Tito. function old new delta adduser_main 650 726 +76 addgroup_main 341 402 +61 addgroup_longopts - 16 +16 adduser_longopts 97 103 +6 packed_usage 26161 26163 +2 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/0 up/down: 161/0) Total: 161 bytes ------------------------------------------------------------------------ Index: include/usage.h =================================================================== --- include/usage.h (revision 26186) +++ include/usage.h (revision 26187) @@ -39,6 +39,7 @@ "Add a group " IF_FEATURE_ADDUSER_TO_GROUP("or add a user to a group") "\n" \ "\nOptions:" \ "\n -g GID Group id" \ + "\n -S Create a system group" \ #define adduser_trivial_usage \ "[OPTIONS] user_name" @@ -52,6 +53,7 @@ "\n -S Create a system user" \ "\n -D Do not assign a password" \ "\n -H Do not create home directory" \ + "\n -u UID User id" \ #define adjtimex_trivial_usage \ "[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]" Index: loginutils/addgroup.c =================================================================== --- loginutils/addgroup.c (revision 26186) +++ loginutils/addgroup.c (revision 26187) @@ -11,34 +11,50 @@ */ #include "libbb.h" +#define OPT_GID (1 << 0) +#define OPT_SYSTEM_ACCOUNT (1 << 1) + +/* We assume GID_T_MAX == INT_MAX */ static void xgroup_study(struct group *g) { + unsigned max = INT_MAX; + /* Make sure gr_name is unused */ if (getgrnam(g->gr_name)) { - goto error; + bb_error_msg_and_die("%s '%s' in use", "group", g->gr_name); + /* these format strings are reused in adduser and addgroup */ } + /* if a specific gid is requested, the --system switch and */ + /* min and max values are overriden, and the range of valid */ + /* gid values is set to [0, INT_MAX] */ + if (!(option_mask32 & OPT_GID)) { + if (option_mask32 & OPT_SYSTEM_ACCOUNT) { + g->gr_gid = 100; /* FIRST_SYSTEM_GID */ + max = 999; /* LAST_SYSTEM_GID */ + } else { + g->gr_gid = 1000; /* FIRST_GID */ + max = 64999; /* LAST_GID */ + } + } /* Check if the desired gid is free * or find the first free one */ while (1) { if (!getgrgid(g->gr_gid)) { return; /* found free group: return */ } - if (option_mask32) { + if (option_mask32 & OPT_GID) { /* -g N, cannot pick gid other than N: error */ - g->gr_name = itoa(g->gr_gid); - goto error; + bb_error_msg_and_die("%s '%s' in use", "gid", itoa(g->gr_gid)); + /* this format strings is reused in adduser and addgroup */ } - g->gr_gid++; - if (g->gr_gid <= 0) { + if (g->gr_gid == max) { /* overflowed: error */ - bb_error_msg_and_die("no gids left"); + bb_error_msg_and_die("no %cids left", 'g'); + /* this format string is reused in adduser and addgroup */ } + g->gr_gid++; } - - error: - /* exit */ - bb_error_msg_and_die("group %s already exists", g->gr_name); } /* append a new user to the passwd file */ @@ -53,7 +69,7 @@ xgroup_study(&gr); /* add entry to group */ - p = xasprintf("x:%u:", gr.gr_gid); + p = xasprintf("x:%u:", (unsigned) gr.gr_gid); if (update_passwd(bb_path_group_file, group, p, NULL) < 0) exit(EXIT_FAILURE); if (ENABLE_FEATURE_CLEAN_UP) @@ -64,6 +80,13 @@ #endif } +#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS +static const char addgroup_longopts[] ALIGN1 = + "gid\0" Required_argument "g" + "system\0" No_argument "S" + ; +#endif + /* * addgroup will take a login_name as its first parameter. * @@ -74,23 +97,23 @@ int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int addgroup_main(int argc UNUSED_PARAM, char **argv) { - char *group; - gid_t gid = 0; + unsigned opts; + unsigned gid = 0; /* need to be root */ if (geteuid()) { bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); } - +#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS + applet_long_options = addgroup_longopts; +#endif /* Syntax: * addgroup group * addgroup -g num group * addgroup user group * Check for min, max and missing args */ - opt_complementary = "-1:?2"; - if (getopt32(argv, "g:", &group)) { - gid = xatoul_range(group, 0, ((unsigned long)(gid_t)ULONG_MAX) >> 1); - } + opt_complementary = "-1:?2:g+"; + opts = getopt32(argv, "g:S", &gid); /* move past the commandline options */ argv += optind; //argc -= optind; @@ -99,7 +122,7 @@ if (argv[1]) { struct group *gr; - if (option_mask32) { + if (opts & OPT_GID) { /* -g was there, but "addgroup -g num user group" * is a no-no */ bb_show_usage(); Index: loginutils/adduser.c =================================================================== --- loginutils/adduser.c (revision 26186) +++ loginutils/adduser.c (revision 26187) @@ -9,38 +9,55 @@ */ #include "libbb.h" +/* #define OPT_HOME (1 << 0) */ /* unused */ +/* #define OPT_GECOS (1 << 1) */ /* unused */ +#define OPT_SHELL (1 << 2) +#define OPT_GID (1 << 3) #define OPT_DONT_SET_PASS (1 << 4) #define OPT_SYSTEM_ACCOUNT (1 << 5) #define OPT_DONT_MAKE_HOME (1 << 6) +#define OPT_UID (1 << 7) +/* We assume UID_T_MAX == INT_MAX */ /* remix */ /* recoded such that the uid may be passed in *p */ static void passwd_study(struct passwd *p) { - int max; + int max = UINT_MAX; - if (getpwnam(p->pw_name)) - bb_error_msg_and_die("login '%s' is in use", p->pw_name); + if (getpwnam(p->pw_name)) { + bb_error_msg_and_die("%s '%s' in use", "user", p->pw_name); + /* this format string is reused in adduser and addgroup */ + } - if (option_mask32 & OPT_SYSTEM_ACCOUNT) { - p->pw_uid = 0; - max = 999; - } else { - p->pw_uid = 1000; - max = 64999; + if (!(option_mask32 & OPT_UID)) { + if (option_mask32 & OPT_SYSTEM_ACCOUNT) { + p->pw_uid = 100; /* FIRST_SYSTEM_UID */ + max = 999; /* LAST_SYSTEM_UID */ + } else { + p->pw_uid = 1000; /* FIRST_UID */ + max = 64999; /* LAST_UID */ + } } - /* check for a free uid (and maybe gid) */ while (getpwuid(p->pw_uid) || (p->pw_gid == (gid_t)-1 && getgrgid(p->pw_uid))) { + if (option_mask32 & OPT_UID) { + /* -u N, cannot pick uid other than N: error */ + bb_error_msg_and_die("%s '%s' in use", "uid", itoa(p->pw_uid)); + /* this format string is reused in adduser and addgroup */ + } + if (p->pw_uid == max) { + bb_error_msg_and_die("no %cids left", 'u'); + } p->pw_uid++; - if (p->pw_uid > max) - bb_error_msg_and_die("no free uids left"); } if (p->pw_gid == (gid_t)-1) { p->pw_gid = p->pw_uid; /* new gid = uid */ - if (getgrnam(p->pw_name)) - bb_error_msg_and_die("group name '%s' is in use", p->pw_name); + if (getgrnam(p->pw_name)) { + bb_error_msg_and_die("%s '%s' in use", "group", p->pw_name); + /* this format string is reused in adduser and addgroup */ + } } } @@ -73,6 +90,7 @@ "empty-password\0" No_argument "D" "system\0" No_argument "S" "no-create-home\0" No_argument "H" + "uid\0" Required_argument "u" ; #endif @@ -87,6 +105,7 @@ struct passwd pw; const char *usegroup = NULL; char *p; + unsigned opts; #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS applet_long_options = adduser_longopts; @@ -102,8 +121,17 @@ pw.pw_dir = NULL; /* exactly one non-option arg */ - opt_complementary = "=1"; - getopt32(argv, "h:g:s:G:DSH", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup); + /* disable interactive passwd for system accounts */ + opt_complementary = "=1:SD:u+"; + if (sizeof(pw.pw_uid) == sizeof(int)) { + opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &pw.pw_uid); + } else { + unsigned uid; + opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid); + if (opts & OPT_UID) { + pw.pw_uid = uid; + } + } argv += optind; /* fill in the passwd struct */ @@ -114,12 +142,22 @@ pw.pw_dir = xasprintf("/home/%s", argv[0]); } pw.pw_passwd = (char *)"x"; + if (opts & OPT_SYSTEM_ACCOUNT) { + if (!usegroup) { + usegroup = "nogroup"; + } + if (!(opts & OPT_SHELL)) { + pw.pw_shell = (char *) "/bin/false"; + } + } pw.pw_gid = usegroup ? xgroup2gid(usegroup) : -1; /* exits on failure */ /* make sure everything is kosher and setup uid && maybe gid */ passwd_study(&pw); - p = xasprintf("x:%u:%u:%s:%s:%s", pw.pw_uid, pw.pw_gid, pw.pw_gecos, pw.pw_dir, pw.pw_shell); + p = xasprintf("x:%u:%u:%s:%s:%s", + (unsigned) pw.pw_uid, (unsigned) pw.pw_gid, + pw.pw_gecos, pw.pw_dir, pw.pw_shell); if (update_passwd(bb_path_passwd_file, pw.pw_name, p, NULL) < 0) { return EXIT_FAILURE; } @@ -143,10 +181,10 @@ /* clear the umask for this process so it doesn't * screw up the permissions on the mkdir and chown. */ umask(0); - if (!(option_mask32 & OPT_DONT_MAKE_HOME)) { - /* Set the owner and group so it is owned by the new user, - then fix up the permissions to 2755. Can't do it before - since chown will clear the setgid bit */ + if (!(opts & OPT_DONT_MAKE_HOME)) { + /* set the owner and group so it is owned by the new user, + * then fix up the permissions to 2755. Can't do it before + * since chown will clear the setgid bit */ if (mkdir(pw.pw_dir, 0755) || chown(pw.pw_dir, pw.pw_uid, pw.pw_gid) || chmod(pw.pw_dir, 02755) /* set setgid bit on homedir */ @@ -155,7 +193,7 @@ } } - if (!(option_mask32 & OPT_DONT_SET_PASS)) { + if (!(opts & OPT_DONT_SET_PASS)) { /* interactively set passwd */ passwd_wrapper(pw.pw_name); } Index: loginutils/Config.in =================================================================== --- loginutils/Config.in (revision 26186) +++ loginutils/Config.in (revision 26187) @@ -97,6 +97,13 @@ help Utility for creating a new group account. +config FEATURE_ADDGROUP_LONG_OPTIONS + bool "Enable long options" + default n + depends on ADDGROUP && GETOPT_LONG + help + Support long options for the addgroup applet. + config FEATURE_ADDUSER_TO_GROUP bool "Support for adding users to groups" default n ------------------------------------------------------------------------ r26186 | vda | 2009-04-22 09:16:59 -0500 (Wed, 22 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/httpd.c httpd: fix small bug in parser. it crept in during cleanup ------------------------------------------------------------------------ Index: networking/httpd.c =================================================================== --- networking/httpd.c (revision 26185) +++ networking/httpd.c (revision 26186) @@ -100,7 +100,6 @@ # include #endif -//#define DEBUG 1 #define DEBUG 0 #define IOBUF_SIZE 8192 /* IO buffer */ @@ -698,13 +697,13 @@ unsigned file_len; /* note: path is "" unless we are in SUBDIR parse, - * otherwise it always starts with "/" */ + * otherwise it does NOT start with "/" */ cur = xzalloc(sizeof(*cur) /* includes space for NUL */ - + strlen(path) + + 1 + strlen(path) + strlen_buf ); /* form "/path/file" */ - sprintf(cur->before_colon, "%s%.*s", + sprintf(cur->before_colon, "/%s%.*s", path, after_colon - buf - 1, /* includes "/", but not ":" */ buf); ------------------------------------------------------------------------ r26185 | vda | 2009-04-22 08:52:22 -0500 (Wed, 22 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/httpd.c httpd: allow empty lines in conf file ------------------------------------------------------------------------ Index: networking/httpd.c =================================================================== --- networking/httpd.c (revision 26184) +++ networking/httpd.c (revision 26185) @@ -546,9 +546,11 @@ } *p = '\0'; strlen_buf = p - buf; + if (strlen_buf == 0) + continue; } - /* empty or strange line? */ + /* strange line? */ if (after_colon == NULL || *after_colon == '\0') goto config_error; ------------------------------------------------------------------------ r26184 | vda | 2009-04-22 08:49:16 -0500 (Wed, 22 Apr 2009) | 14 lines Changed paths: M /trunk/busybox/include/libbb.h M /trunk/busybox/libbb/simplify_path.c M /trunk/busybox/networking/httpd.c httpd: simplify insane conf file parser function old new delta bb_simplify_abs_path_inplace - 98 +98 parse_expr 824 832 +8 passwd_main 1025 1027 +2 evalvar 1374 1376 +2 parse_command 1463 1460 -3 bb_simplify_path 137 55 -82 parse_conf 1572 1422 -150 ------------------------------------------------------------------------------ (add/remove: 3/2 grow/shrink: 3/3 up/down: 126/-251) Total: -125 bytes ------------------------------------------------------------------------ Index: networking/httpd.c =================================================================== --- networking/httpd.c (revision 26183) +++ networking/httpd.c (revision 26184) @@ -54,7 +54,7 @@ * /adm:admin:setup # Require user admin, pwd setup on urls starting with /adm/ * /adm:toor:PaSsWd # or user toor, pwd PaSsWd on urls starting with /adm/ * .au:audio/basic # additional mime type for audio.au files - * *.php:/path/php # running cgi.php scripts through an interpreter + * *.php:/path/php # run xxx.php through an interpreter * * A/D may be as a/d or allow/deny - only first char matters. * Deny/Allow IP logic: @@ -115,8 +115,8 @@ #define HEADER_READ_TIMEOUT 60 -static const char default_path_httpd_conf[] ALIGN1 = "/etc"; -static const char httpd_conf[] ALIGN1 = "httpd.conf"; +static const char DEFAULT_PATH_HTTPD_CONF[] ALIGN1 = "/etc"; +static const char HTTPD_CONF[] ALIGN1 = "httpd.conf"; static const char HTTP_200[] ALIGN1 = "HTTP/1.0 200 OK\r\n"; typedef struct has_next_ptr { @@ -242,7 +242,7 @@ const char *bind_addr_or_port; const char *g_query; - const char *configFile; + const char *opt_c_configFile; const char *home_httpd; const char *index_page; @@ -289,7 +289,7 @@ #define rmt_ip (G.rmt_ip ) #define bind_addr_or_port (G.bind_addr_or_port) #define g_query (G.g_query ) -#define configFile (G.configFile ) +#define opt_c_configFile (G.opt_c_configFile ) #define home_httpd (G.home_httpd ) #define index_page (G.index_page ) #define found_mime_type (G.found_mime_type ) @@ -452,14 +452,6 @@ /* * Parse configuration file into in-memory linked list. * - * The first non-white character is examined to determine if the config line - * is one of the following: - * .ext:mime/type # new mime type not compiled into httpd - * [adAD]:from # ip address allow/deny, * for wildcard - * /path:user:pass # username/password - * Ennn:error.html # error page for status nnn - * P:/url:[http://]hostname[:port]/new/path # reverse proxy - * * Any previous IP rules are discarded. * If the flag argument is not SUBDIR_PARSE then all /path and mime rules * are also discarded. That is, previous settings are retained if flag is @@ -469,99 +461,136 @@ * path Path where to look for httpd.conf (without filename). * flag Type of the parse request. */ -/* flag */ -#define FIRST_PARSE 0 -#define SUBDIR_PARSE 1 -#define SIGNALED_PARSE 2 -#define FIND_FROM_HTTPD_ROOT 3 +/* flag param: */ +enum { + FIRST_PARSE = 0, /* path will be "/etc" */ + SIGNALED_PARSE = 1, /* path will be "/etc" */ + SUBDIR_PARSE = 2, /* path will be derived from URL */ +}; static void parse_conf(const char *path, int flag) { + /* internally used extra flag state */ + enum { TRY_CURDIR_PARSE = 3 }; + FILE *f; -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH - Htaccess *prev; -#endif - Htaccess *cur; - const char *filename = configFile; + const char *filename; char buf[160]; - char *p, *p0; - char *after_colon; - Htaccess_IP *pip; /* discard old rules */ free_Htaccess_IP_list(&ip_a_d); flg_deny_all = 0; /* retain previous auth and mime config only for subdir parse */ if (flag != SUBDIR_PARSE) { + free_Htaccess_list(&mime_a); #if ENABLE_FEATURE_HTTPD_BASIC_AUTH free_Htaccess_list(&g_auth); #endif - free_Htaccess_list(&mime_a); #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR free_Htaccess_list(&script_i); #endif } + filename = opt_c_configFile; if (flag == SUBDIR_PARSE || filename == NULL) { - filename = alloca(strlen(path) + sizeof(httpd_conf) + 2); - sprintf((char *)filename, "%s/%s", path, httpd_conf); + filename = alloca(strlen(path) + sizeof(HTTPD_CONF) + 2); + sprintf((char *)filename, "%s/%s", path, HTTPD_CONF); } while ((f = fopen_for_read(filename)) == NULL) { - if (flag == SUBDIR_PARSE || flag == FIND_FROM_HTTPD_ROOT) { + if (flag >= SUBDIR_PARSE) { /* SUBDIR or TRY_CURDIR */ /* config file not found, no changes to config */ return; } - if (configFile && flag == FIRST_PARSE) /* if -c option given */ - bb_simple_perror_msg_and_die(filename); - flag = FIND_FROM_HTTPD_ROOT; - filename = httpd_conf; + if (flag == FIRST_PARSE) { + /* -c CONFFILE given, but CONFFILE doesn't exist? */ + if (opt_c_configFile) + bb_simple_perror_msg_and_die(opt_c_configFile); + /* else: no -c, thus we looked at /etc/httpd.conf, + * and it's not there. try ./httpd.conf: */ + } + flag = TRY_CURDIR_PARSE; + filename = HTTPD_CONF; } #if ENABLE_FEATURE_HTTPD_BASIC_AUTH - prev = g_auth; + /* in "/file:user:pass" lines, we prepend path in subdirs */ + if (flag != SUBDIR_PARSE) + path = ""; #endif - /* This could stand some work */ - while ((p0 = fgets(buf, sizeof(buf), f)) != NULL) { - after_colon = NULL; - for (p = p0; *p0 != '\0' && *p0 != '#'; p0++) { - if (!isspace(*p0)) { - *p++ = *p0; - if (*p0 == ':' && after_colon == NULL) - after_colon = p; + /* The lines can be: + * + * I:default_index_file + * H:http_home + * [AD]:IP[/mask] # allow/deny, * for wildcard + * Ennn:error.html # error page for status nnn + * P:/url:[http://]hostname[:port]/new/path # reverse proxy + * .ext:mime/type # mime type + * *.php:/path/php # run xxx.php through an interpreter + * /file:user:pass # username and password + */ + while (fgets(buf, sizeof(buf), f) != NULL) { + unsigned strlen_buf; + unsigned char ch; + char *after_colon = NULL; + + { /* remove all whitespace, and # comments */ + char *p, *p0; + + p = p0 = buf; + while ((ch = *p0++) != '\0' && ch != '#') { + if (!isspace(ch)) { + *p++ = ch; + if (ch == ':' && after_colon == NULL) + after_colon = p; + } } + *p = '\0'; + strlen_buf = p - buf; } - *p = '\0'; - /* test for empty or strange line */ + /* empty or strange line? */ if (after_colon == NULL || *after_colon == '\0') + goto config_error; + + ch = (buf[0] & ~0x20); /* toupper if it's a letter */ + + if (ch == 'I') { + index_page = xstrdup(after_colon); continue; - p0 = buf; - if (*p0 == 'd' || *p0 == 'a') - *p0 -= 0x20; /* a/d -> A/D */ - if (*after_colon == '*') { - if (*p0 == 'D') { - /* memorize "deny all" */ - flg_deny_all = 1; - } - /* skip assumed "A:*", it is a default anyway */ + } + + /* do not allow jumping around using H in subdir's configs */ + if (flag == FIRST_PARSE && ch == 'H') { + home_httpd = xstrdup(after_colon); + xchdir(home_httpd); continue; } - if (*p0 == 'A' || *p0 == 'D') { - /* storing current config IP line */ - pip = xzalloc(sizeof(Htaccess_IP)); - if (scan_ip_mask(after_colon, &(pip->ip), &(pip->mask))) { + if (ch == 'A' || ch == 'D') { + Htaccess_IP *pip; + + if (*after_colon == '*') { + if (ch == 'D') { + /* memorize "deny all" */ + flg_deny_all = 1; + } + /* skip assumed "A:*", it is a default anyway */ + continue; + } + /* store "allow/deny IP/mask" line */ + pip = xzalloc(sizeof(*pip)); + if (scan_ip_mask(after_colon, &pip->ip, &pip->mask)) { /* IP{/mask} syntax error detected, protect all */ - *p0 = 'D'; + ch = 'D'; pip->mask = 0; } - pip->allow_deny = *p0; - if (*p0 == 'D') { + pip->allow_deny = ch; + if (ch == 'D') { /* Deny:from_IP - prepend */ pip->next = ip_a_d; ip_a_d = pip; } else { - /* A:from_IP - append (thus D precedes A) */ + /* A:from_IP - append (thus all D's precedes A's) */ Htaccess_IP *prev_IP = ip_a_d; if (prev_IP == NULL) { ip_a_d = pip; @@ -575,12 +604,12 @@ } #if ENABLE_FEATURE_HTTPD_ERROR_PAGES - if (flag == FIRST_PARSE && *p0 == 'E') { + if (flag == FIRST_PARSE && ch == 'E') { unsigned i; - int status = atoi(++p0); /* error status code */ + int status = atoi(buf + 1); /* error status code */ + if (status < HTTP_CONTINUE) { - bb_error_msg("config error '%s' in '%s'", buf, filename); - continue; + goto config_error; } /* then error page; find matching status */ for (i = 0; i < ARRAY_SIZE(http_response_type); i++) { @@ -597,7 +626,7 @@ #endif #if ENABLE_FEATURE_HTTPD_PROXY - if (flag == FIRST_PARSE && *p0 == 'P') { + if (flag == FIRST_PARSE && ch == 'P') { /* P:/url:[http://]hostname[:port]/new/path */ char *url_from, *host_port, *url_to; Htaccess_Proxy *proxy_entry; @@ -605,23 +634,20 @@ url_from = after_colon; host_port = strchr(after_colon, ':'); if (host_port == NULL) { - bb_error_msg("config error '%s' in '%s'", buf, filename); - continue; + goto config_error; } *host_port++ = '\0'; if (strncmp(host_port, "http://", 7) == 0) host_port += 7; if (*host_port == '\0') { - bb_error_msg("config error '%s' in '%s'", buf, filename); - continue; + goto config_error; } url_to = strchr(host_port, '/'); if (url_to == NULL) { - bb_error_msg("config error '%s' in '%s'", buf, filename); - continue; + goto config_error; } *url_to = '\0'; - proxy_entry = xzalloc(sizeof(Htaccess_Proxy)); + proxy_entry = xzalloc(sizeof(*proxy_entry)); proxy_entry->url_from = xstrdup(url_from); proxy_entry->host_port = xstrdup(host_port); *url_to = '/'; @@ -631,115 +657,87 @@ continue; } #endif + /* the rest of directives are non-alphabetic, + * must avoid using "toupper'ed" ch */ + ch = buf[0]; -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH - if (*p0 == '/') { - /* make full path from httpd root / current_path / config_line_path */ - const char *tp = (flag == SUBDIR_PARSE ? path : ""); - p0 = xmalloc(strlen(tp) + (after_colon - buf) + 2 + strlen(after_colon)); - after_colon[-1] = '\0'; - sprintf(p0, "/%s%s", tp, buf); + if (ch == '.' /* ".ext:mime/type" */ +#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR + || (ch == '*' && buf[1] == '.') /* "*.php:/path/php" */ +#endif + ) { + char *p; + Htaccess *cur; - /* looks like bb_simplify_path... */ - tp = p = p0; - do { - if (*p == '/') { - if (*tp == '/') { /* skip duplicate (or initial) slash */ - continue; - } - if (*tp == '.') { - if (tp[1] == '/' || tp[1] == '\0') { /* remove extra '.' */ - continue; - } - if ((tp[1] == '.') && (tp[2] == '/' || tp[2] == '\0')) { - ++tp; - if (p > p0) { - while (*--p != '/') /* omit previous dir */ - continue; - } - continue; - } - } - } - *++p = *tp; - } while (*++tp); - - if ((p == p0) || (*p != '/')) { /* not a trailing slash */ - ++p; /* so keep last character */ + cur = xzalloc(sizeof(*cur) /* includes space for NUL */ + strlen_buf); + strcpy(cur->before_colon, buf); + p = cur->before_colon + (after_colon - buf); + p[-1] = '\0'; + cur->after_colon = p; + if (ch == '.') { + /* .mime line: prepend to mime_a list */ + cur->next = mime_a; + mime_a = cur; } - *p = ':'; - strcpy(p + 1, after_colon); - } +#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR + else { + /* script interpreter line: prepend to script_i list */ + cur->next = script_i; + script_i = cur; + } #endif - if (*p0 == 'I') { - index_page = xstrdup(after_colon); continue; } - /* Do not allow jumping around using H in subdir's configs */ - if (flag == FIRST_PARSE && *p0 == 'H') { - home_httpd = xstrdup(after_colon); - xchdir(home_httpd); - continue; - } - - /* storing current config line */ - cur = xzalloc(sizeof(Htaccess) + strlen(p0)); - strcpy(cur->before_colon, p0); #if ENABLE_FEATURE_HTTPD_BASIC_AUTH - if (*p0 == '/') /* was malloced - see above */ - free(p0); -#endif - cur->after_colon = strchr(cur->before_colon, ':'); - *cur->after_colon++ = '\0'; - if (cur->before_colon[0] == '.') { - /* .mime line: prepend to mime_a list */ - cur->next = mime_a; - mime_a = cur; - continue; - } -#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR - if (cur->before_colon[0] == '*' && cur->before_colon[1] == '.') { - /* script interpreter line: prepend to script_i list */ - cur->next = script_i; - script_i = cur; - continue; - } -#endif -#if ENABLE_FEATURE_HTTPD_BASIC_AUTH -//TODO: we do not test for leading "/"?? -//also, do we leak cur if BASIC_AUTH is off? - if (prev == NULL) { - /* first line */ - g_auth = prev = cur; - } else { - /* sort path, if current length eq or bigger then move up */ - Htaccess *prev_hti = g_auth; - size_t l = strlen(cur->before_colon); - Htaccess *hti; + if (ch == '/') { /* "/file:user:pass" */ + char *p; + Htaccess *cur; + unsigned file_len; - for (hti = prev_hti; hti; hti = hti->next) { - if (l >= strlen(hti->before_colon)) { - /* insert before hti */ - cur->next = hti; - if (prev_hti != hti) { - prev_hti->next = cur; - } else { - /* insert as top */ - g_auth = cur; + /* note: path is "" unless we are in SUBDIR parse, + * otherwise it always starts with "/" */ + cur = xzalloc(sizeof(*cur) /* includes space for NUL */ + + strlen(path) + + strlen_buf + ); + /* form "/path/file" */ + sprintf(cur->before_colon, "%s%.*s", + path, + after_colon - buf - 1, /* includes "/", but not ":" */ + buf); + /* canonicalize it */ + p = bb_simplify_abs_path_inplace(cur->before_colon); + file_len = p - cur->before_colon; + /* add "user:pass" after NUL */ + strcpy(++p, after_colon); + cur->after_colon = p; + + /* insert cur into g_auth */ + /* g_auth is sorted by decreased filename length */ + { + Htaccess *auth, **authp; + + authp = &g_auth; + while ((auth = *authp) != NULL) { + if (file_len >= strlen(auth->before_colon)) { + /* insert cur before auth */ + cur->next = auth; + break; } - break; + authp = &auth->next; } - if (prev_hti != hti) - prev_hti = prev_hti->next; + *authp = cur; } - if (!hti) { /* not inserted, add to bottom */ - prev->next = cur; - prev = cur; - } + continue; } #endif /* BASIC_AUTH */ + + /* the line is not recognized */ + config_error: + bb_error_msg("config error '%s' in '%s'", buf, filename); } /* while (fgets) */ + fclose(f); } @@ -2031,8 +2029,8 @@ /* We are done reading headers, disable peer timeout */ alarm(0); - if (strcmp(bb_basename(urlcopy), httpd_conf) == 0 || !ip_allowed) { - /* protect listing [/path]/httpd_conf or IP deny */ + if (strcmp(bb_basename(urlcopy), HTTPD_CONF) == 0 || !ip_allowed) { + /* protect listing [/path]/httpd.conf or IP deny */ send_headers_and_exit(HTTP_FORBIDDEN); } @@ -2245,7 +2243,7 @@ static void sighup_handler(int sig UNUSED_PARAM) { - parse_conf(default_path_httpd_conf, SIGNALED_PARSE); + parse_conf(DEFAULT_PATH_HTTPD_CONF, SIGNALED_PARSE); } enum { @@ -2304,7 +2302,7 @@ IF_FEATURE_HTTPD_AUTH_MD5("m:") IF_FEATURE_HTTPD_SETUID("u:") "p:ifv", - &configFile, &url_for_decode, &home_httpd + &opt_c_configFile, &url_for_decode, &home_httpd IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) IF_FEATURE_HTTPD_AUTH_MD5(, &pass) @@ -2375,7 +2373,7 @@ } #endif - parse_conf(default_path_httpd_conf, FIRST_PARSE); + parse_conf(DEFAULT_PATH_HTTPD_CONF, FIRST_PARSE); if (!(opt & OPT_INETD)) signal(SIGHUP, sighup_handler); Index: libbb/simplify_path.c =================================================================== --- libbb/simplify_path.c (revision 26183) +++ libbb/simplify_path.c (revision 26184) @@ -6,22 +6,13 @@ * * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ - #include "libbb.h" -char* FAST_FUNC bb_simplify_path(const char *path) +char* FAST_FUNC bb_simplify_abs_path_inplace(char *start) { - char *s, *start, *p; + char *s, *p; - if (path[0] == '/') - start = xstrdup(path); - else { - s = xrealloc_getcwd_or_warn(NULL); - start = concat_path_file(s, path); - free(s); - } p = s = start; - do { if (*p == '/') { if (*s == '/') { /* skip duplicate (or initial) slash */ @@ -47,7 +38,22 @@ if ((p == start) || (*p != '/')) { /* not a trailing slash */ ++p; /* so keep last character */ } - *p = 0; + *p = '\0'; + return p; +} - return start; +char* FAST_FUNC bb_simplify_path(const char *path) +{ + char *s, *p; + + if (path[0] == '/') + s = xstrdup(path); + else { + p = xrealloc_getcwd_or_warn(NULL); + s = concat_path_file(p, path); + free(p); + } + + bb_simplify_abs_path_inplace(s); + return s; } Index: include/libbb.h =================================================================== --- include/libbb.h (revision 26183) +++ include/libbb.h (revision 26184) @@ -1093,6 +1093,8 @@ void print_signames(void) FAST_FUNC; char *bb_simplify_path(const char *path) FAST_FUNC; +/* Returns ptr to NUL */ +char *bb_simplify_abs_path_inplace(char *path) FAST_FUNC; #define FAIL_DELAY 3 extern void bb_do_delay(int seconds) FAST_FUNC; ------------------------------------------------------------------------ r26181 | vda | 2009-04-21 21:53:02 -0500 (Tue, 21 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/sysklogd/syslogd.c syslogd: added comment, no code changes ------------------------------------------------------------------------ Index: sysklogd/syslogd.c =================================================================== --- sysklogd/syslogd.c (revision 26180) +++ sysklogd/syslogd.c (revision 26181) @@ -423,6 +423,8 @@ char *timestamp; time_t now; + /* Jan 18 00:11:22 msg... */ + /* 01234567890123456 */ if (len < 16 || msg[3] != ' ' || msg[6] != ' ' || msg[9] != ':' || msg[12] != ':' || msg[15] != ' ' ) { ------------------------------------------------------------------------ r26180 | vda | 2009-04-21 19:26:39 -0500 (Tue, 21 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/include/usage.h httpd: improve help text ------------------------------------------------------------------------ Index: include/usage.h =================================================================== --- include/usage.h (revision 26179) +++ include/usage.h (revision 26180) @@ -1631,29 +1631,28 @@ "sage\n" #define httpd_trivial_usage \ - "[-c conffile]" \ - " [-p [ip:]port]" \ - " [-i] [-f] [-v[v]]" \ - IF_FEATURE_HTTPD_SETUID(" [-u user[:grp]]") \ - IF_FEATURE_HTTPD_BASIC_AUTH(" [-r realm]") \ - IF_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \ - " [-h home]" \ - " [-d/-e string]" + "[-ifv[v]]" \ + " [-c CONFFILE]" \ + " [-p [IP:]PORT]" \ + IF_FEATURE_HTTPD_SETUID(" [-u USER[:GRP]]") \ + IF_FEATURE_HTTPD_BASIC_AUTH(" [-r REALM]") \ + " [-h HOME]\n" \ + "or httpd -d/-e" IF_FEATURE_HTTPD_AUTH_MD5("/-m") " STRING" #define httpd_full_usage "\n\n" \ "Listen for incoming HTTP requests\n" \ "\nOptions:" \ - "\n -c FILE Configuration file (default httpd.conf)" \ - "\n -p [IP:]PORT Bind to ip:port (default *:80)" \ "\n -i Inetd mode" \ "\n -f Do not daemonize" \ "\n -v[v] Verbose" \ + "\n -c FILE Configuration file (default httpd.conf)" \ + "\n -p [IP:]PORT Bind to ip:port (default *:80)" \ IF_FEATURE_HTTPD_SETUID( \ "\n -u USER[:GRP] Set uid/gid after binding to port") \ IF_FEATURE_HTTPD_BASIC_AUTH( \ "\n -r REALM Authentication Realm for Basic Authentication") \ - IF_FEATURE_HTTPD_AUTH_MD5( \ - "\n -m PASS Crypt PASS with md5 algorithm") \ "\n -h HOME Home directory (default .)" \ + IF_FEATURE_HTTPD_AUTH_MD5( \ + "\n -m STRING MD5 crypt STRING") \ "\n -e STRING HTML encode STRING" \ "\n -d STRING URL decode STRING" \ ------------------------------------------------------------------------ r26179 | vda | 2009-04-21 18:51:43 -0500 (Tue, 21 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/nc.c nc: free lsa in server mode, we might be up for a long time ------------------------------------------------------------------------ Index: networking/nc.c =================================================================== --- networking/nc.c (revision 26178) +++ networking/nc.c (revision 26179) @@ -111,12 +111,12 @@ /* If we didn't specify a port number, * query and print it after listen() */ if (!lport) { - socklen_t addrlen = lsa->len; - getsockname(sfd, &lsa->u.sa, &addrlen); + getsockname(sfd, &lsa->u.sa, &lsa->len); lport = get_nport(&lsa->u.sa); fdprintf(2, "%d\n", ntohs(lport)); } close_on_exec_on(sfd); + free(lsa); accept_again: cfd = accept(sfd, NULL, 0); if (cfd < 0) ------------------------------------------------------------------------ r26178 | vda | 2009-04-21 18:48:38 -0500 (Tue, 21 Apr 2009) | 11 lines Changed paths: M /trunk/busybox/libbb/xconnect.c M /trunk/busybox/networking/arping.c M /trunk/busybox/networking/libiproute/iplink.c M /trunk/busybox/networking/libiproute/libnetlink.c M /trunk/busybox/networking/libiproute/libnetlink.h M /trunk/busybox/networking/nc_bloaty.c *: remove check for errors on getsockaddr in cases we know they can't happen libbb: make get_sock_lsa use only one getsockaddr syscall, not two function old new delta get_sock_lsa 72 101 +29 do_iplink 1151 1137 -14 arping_main 1585 1569 -16 dolisten 789 755 -34 xrtnl_open 161 94 -67 ------------------------------------------------------------------------ Index: networking/nc_bloaty.c =================================================================== --- networking/nc_bloaty.c (revision 26177) +++ networking/nc_bloaty.c (revision 26178) @@ -278,9 +278,9 @@ random unknown port is probably not very useful without "netstat". */ if (o_verbose) { char *addr; - rr = getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); - if (rr < 0) - bb_perror_msg_and_die("getsockname after bind"); + getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); + //if (rr < 0) + // bb_perror_msg_and_die("getsockname after bind"); addr = xmalloc_sockaddr2dotted(&ouraddr->u.sa); fprintf(stderr, "listening on %s ...\n", addr); free(addr); @@ -359,9 +359,9 @@ doing a listen-on-any on a multihomed machine. This allows one to offer different services via different alias addresses, such as the "virtual web site" hack. */ - rr = getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); - if (rr < 0) - bb_perror_msg_and_die("getsockname after accept"); + getsockname(netfd, &ouraddr->u.sa, &ouraddr->len); + //if (rr < 0) + // bb_perror_msg_and_die("getsockname after accept"); } if (o_verbose) { Index: networking/libiproute/libnetlink.h =================================================================== --- networking/libiproute/libnetlink.h (revision 26177) +++ networking/libiproute/libnetlink.h (revision 26178) @@ -10,8 +10,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -struct rtnl_handle -{ +struct rtnl_handle { int fd; struct sockaddr_nl local; struct sockaddr_nl peer; Index: networking/libiproute/iplink.c =================================================================== --- networking/libiproute/iplink.c (revision 26177) +++ networking/libiproute/iplink.c (revision 26178) @@ -112,11 +112,11 @@ me.sll_ifindex = ifr.ifr_ifindex; me.sll_protocol = htons(ETH_P_LOOP); xbind(s, (struct sockaddr*)&me, sizeof(me)); - alen = sizeof(me); - if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { - bb_perror_msg_and_die("getsockname"); - } + getsockname(s, (struct sockaddr*)&me, &alen); + //never happens: + //if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) + // bb_perror_msg_and_die("getsockname"); close(s); *htype = me.sll_hatype; return me.sll_halen; Index: networking/libiproute/libnetlink.c =================================================================== --- networking/libiproute/libnetlink.c (revision 26177) +++ networking/libiproute/libnetlink.c (revision 26178) @@ -26,22 +26,23 @@ { socklen_t addr_len; - memset(rth, 0, sizeof(rth)); - + memset(rth, 0, sizeof(*rth)); rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - - memset(&rth->local, 0, sizeof(rth->local)); rth->local.nl_family = AF_NETLINK; /*rth->local.nl_groups = subscriptions;*/ xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); addr_len = sizeof(rth->local); + getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len); + +/* too much paranoia if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) bb_perror_msg_and_die("getsockname"); if (addr_len != sizeof(rth->local)) bb_error_msg_and_die("wrong address length %d", addr_len); if (rth->local.nl_family != AF_NETLINK) bb_error_msg_and_die("wrong address family %d", rth->local.nl_family); +*/ rth->seq = time(NULL); return 0; } Index: networking/arping.c =================================================================== --- networking/arping.c (revision 26177) +++ networking/arping.c (revision 26178) @@ -348,9 +348,10 @@ if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) bb_perror_msg("setsockopt(SO_DONTROUTE)"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); - if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { - bb_perror_msg_and_die("getsockname"); - } + getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); + //never happens: + //if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) + // bb_perror_msg_and_die("getsockname"); if (saddr.sin_family != AF_INET) bb_error_msg_and_die("no IP address configured"); src = saddr.sin_addr; @@ -365,10 +366,10 @@ { socklen_t alen = sizeof(me); - - if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) { - bb_perror_msg_and_die("getsockname"); - } + getsockname(sock_fd, (struct sockaddr *) &me, &alen); + //never happens: + //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) + // bb_perror_msg_and_die("getsockname"); } if (me.sll_halen == 0) { bb_error_msg(err_str, "is not ARPable (no ll address)"); Index: libbb/xconnect.c =================================================================== --- libbb/xconnect.c (revision 26177) +++ libbb/xconnect.c (revision 26178) @@ -37,16 +37,21 @@ len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd) { - len_and_sockaddr *lsa; - socklen_t len = 0; + len_and_sockaddr lsa; + len_and_sockaddr *lsa_ptr; - /* Can be optimized to do only one getsockname() */ - if (getsockname(fd, NULL, &len) != 0) + lsa.len = LSA_SIZEOF_SA; + if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0) return NULL; - lsa = xzalloc(LSA_LEN_SIZE + len); - lsa->len = len; - getsockname(fd, &lsa->u.sa, &lsa->len); - return lsa; + + lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len); + if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */ + lsa_ptr->len = lsa.len; + getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len); + } else { + memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len); + } + return lsa_ptr; } void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) ------------------------------------------------------------------------ r26177 | vda | 2009-04-21 15:52:58 -0500 (Tue, 21 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/switch_root.c switch_root: move misplaced comment ------------------------------------------------------------------------ Index: util-linux/switch_root.c =================================================================== --- util-linux/switch_root.c (revision 26176) +++ util-linux/switch_root.c (revision 26177) @@ -103,8 +103,8 @@ // For example, fails when newroot is not a mountpoint bb_perror_msg_and_die("error moving root"); } + xchroot("."); // The chdir is needed to recalculate "." and ".." links - xchroot("."); xchdir("/"); // If a new console specified, redirect stdin/stdout/stderr to it ------------------------------------------------------------------------ r26176 | vda | 2009-04-21 15:40:51 -0500 (Tue, 21 Apr 2009) | 4 lines Changed paths: M /trunk/busybox/archival/libunarchive/open_transformer.c M /trunk/busybox/archival/tar.c M /trunk/busybox/coreutils/chroot.c M /trunk/busybox/debianutils/run_parts.c M /trunk/busybox/include/usage.h M /trunk/busybox/loginutils/adduser.c M /trunk/busybox/selinux/runcon.c M /trunk/busybox/shell/cttyhack.c M /trunk/busybox/shell/hush.c M /trunk/busybox/util-linux/switch_root.c switch_root: improve behavior on error; improve help text *: make "can't execute '%s'" message uniform ------------------------------------------------------------------------ Index: archival/tar.c =================================================================== --- archival/tar.c (revision 26175) +++ archival/tar.c (revision 26176) @@ -577,7 +577,7 @@ #endif if (vfork_exec_errno) { errno = vfork_exec_errno; - bb_perror_msg_and_die("cannot exec %s", zip_exec); + bb_perror_msg_and_die("can't execute '%s'", zip_exec); } } #endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */ Index: archival/libunarchive/open_transformer.c =================================================================== --- archival/libunarchive/open_transformer.c (revision 26175) +++ archival/libunarchive/open_transformer.c (revision 26176) @@ -52,7 +52,7 @@ argv[2] = (char*)"-"; argv[3] = NULL; BB_EXECVP(transform_prog, argv); - bb_perror_msg_and_die("can't exec %s", transform_prog); + bb_perror_msg_and_die("can't execute '%s'", transform_prog); } #endif /* notreached */ Index: debianutils/run_parts.c =================================================================== --- debianutils/run_parts.c (revision 26175) +++ debianutils/run_parts.c (revision 26176) @@ -164,7 +164,7 @@ continue; n = 1; if (ret < 0) - bb_perror_msg("can't exec %s", name); + bb_perror_msg("can't execute '%s'", name); else /* ret > 0 */ bb_error_msg("%s exited with code %d", name, ret); } Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26175) +++ shell/hush.c (revision 26176) @@ -3048,7 +3048,7 @@ debug_printf_exec("execing '%s'\n", argv[0]); sigprocmask(SIG_SETMASK, &G.inherited_set, NULL); execvp(argv[0], argv); - bb_perror_msg("can't exec '%s'", argv[0]); + bb_perror_msg("can't execute '%s'", argv[0]); _exit(EXIT_FAILURE); } Index: shell/cttyhack.c =================================================================== --- shell/cttyhack.c (revision 26175) +++ shell/cttyhack.c (revision 26176) @@ -73,5 +73,5 @@ } BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("cannot exec '%s'", argv[0]); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); } Index: coreutils/chroot.c =================================================================== --- coreutils/chroot.c (revision 26175) +++ coreutils/chroot.c (revision 26176) @@ -33,5 +33,5 @@ } BB_EXECVP(*argv, argv); - bb_perror_msg_and_die("cannot execute %s", *argv); + bb_perror_msg_and_die("can't execute '%s'", *argv); } Index: include/usage.h =================================================================== --- include/usage.h (revision 26175) +++ include/usage.h (revision 26176) @@ -4125,12 +4125,13 @@ ) \ #define switch_root_trivial_usage \ - "[-c /dev/console] NEW_ROOT NEW_INIT [ARGUMENTS_TO_INIT]" + "[-c /dev/console] NEW_ROOT NEW_INIT [ARG...]" #define switch_root_full_usage "\n\n" \ - "Use from PID 1 under initramfs to free initramfs, chroot to NEW_ROOT,\n" \ - "and exec NEW_INIT\n" \ + "Free initramfs and switch to another root fs:\n" \ + "chroot to NEW_ROOT, delete all in /, move NEW_ROOT to /,\n" \ + "execute NEW_INIT. PID must be 1. NEW_ROOT must be a mountpoint.\n" \ "\nOptions:" \ - "\n -c Redirect console to device on new root" \ + "\n -c DEV Reopen stdio to DEV after switch" \ #define sync_trivial_usage \ "" @@ -4142,7 +4143,7 @@ #define sysctl_full_usage "\n\n" \ "Configure kernel parameters at runtime\n" \ "\nOptions:" \ - "\n -n Disable printing of key names" \ + "\n -n Don't print key names" \ "\n -e Don't warn about unknown keys" \ "\n -w Change sysctl setting" \ "\n -p FILE Load sysctl settings from FILE (default /etc/sysctl.conf)" \ Index: selinux/runcon.c =================================================================== --- selinux/runcon.c (revision 26175) +++ selinux/runcon.c (revision 26176) @@ -129,10 +129,10 @@ context_str(con)); if (setexeccon(context_str(con))) - bb_error_msg_and_die("cannot set up security context '%s'", + bb_error_msg_and_die("can't set up security context '%s'", context_str(con)); execvp(argv[0], argv); - bb_perror_msg_and_die("cannot execute '%s'", argv[0]); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); } Index: loginutils/adduser.c =================================================================== --- loginutils/adduser.c (revision 26175) +++ loginutils/adduser.c (revision 26176) @@ -60,7 +60,7 @@ static const char prog[] ALIGN1 = "passwd"; BB_EXECLP(prog, prog, login, NULL); - bb_error_msg_and_die("cannot execute %s, you must set password manually", prog); + bb_error_msg_and_die("can't execute %s, you must set password manually", prog); } #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS Index: util-linux/switch_root.c =================================================================== --- util-linux/switch_root.c (revision 26175) +++ util-linux/switch_root.c (revision 26176) @@ -5,11 +5,10 @@ * * Licensed under GPL version 2, see file LICENSE in this tarball for details. */ - #include "libbb.h" #include -// Make up for header deficiencies. +// Make up for header deficiencies #ifndef RAMFS_MAGIC #define RAMFS_MAGIC ((unsigned)0x858458f6) #endif @@ -22,7 +21,7 @@ #define MS_MOVE 8192 #endif -// Recursively delete contents of rootfs. +// Recursively delete contents of rootfs static void delete_contents(const char *directory, dev_t rootdev) { DIR *dir; @@ -33,7 +32,7 @@ if (lstat(directory, &st) || st.st_dev != rootdev) return; - // Recursively delete the contents of directories. + // Recursively delete the contents of directories if (S_ISDIR(st.st_mode)) { dir = opendir(directory); if (dir) { @@ -51,42 +50,47 @@ } closedir(dir); - // Directory should now be empty. Zap it. + // Directory should now be empty, zap it rmdir(directory); } - - // It wasn't a directory. Zap it. - } else unlink(directory); + } else { + // It wasn't a directory, zap it + unlink(directory); + } } int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int switch_root_main(int argc UNUSED_PARAM, char **argv) { char *newroot, *console = NULL; - struct stat st1, st2; + struct stat st; struct statfs stfs; dev_t rootdev; // Parse args (-c console) opt_complementary = "-2"; // minimum 2 params - getopt32(argv, "+c:", &console); // '+': stop parsing at first non-option + getopt32(argv, "+c:", &console); // '+': stop at first non-option argv += optind; - - // Change to new root directory and verify it's a different fs. newroot = *argv++; + // Change to new root directory and verify it's a different fs xchdir(newroot); - if (lstat(".", &st1) || lstat("/", &st2) || st1.st_dev == st2.st_dev) { - bb_error_msg_and_die("bad newroot %s", newroot); + xstat("/", &st); + rootdev = st.st_dev; + xstat(".", &st); + if (st.st_dev == rootdev || getpid() != 1) { + // Show usage, it says new root must be a mountpoint + // and we must be PID 1 + bb_show_usage(); } - rootdev = st2.st_dev; - // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE - // we mean it. (I could make this a CONFIG option, but I would get email - // from all the people who WILL eat their filesystems.) - if (lstat("/init", &st1) || !S_ISREG(st1.st_mode) || statfs("/", &stfs) - || (((unsigned)stfs.f_type != RAMFS_MAGIC) && ((unsigned)stfs.f_type != TMPFS_MAGIC)) - || (getpid() != 1) + // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE + // we mean it. I could make this a CONFIG option, but I would get email + // from all the people who WILL destroy their filesystems. + statfs("/", &stfs); // this never fails + if (lstat("/init", &st) != 0 || !S_ISREG(st.st_mode) + || ((unsigned)stfs.f_type != RAMFS_MAGIC + && (unsigned)stfs.f_type != TMPFS_MAGIC) ) { bb_error_msg_and_die("not rootfs"); } @@ -94,14 +98,16 @@ // Zap everything out of rootdev delete_contents("/", rootdev); - // Overmount / with newdir and chroot into it. The chdir is needed to - // recalculate "." and ".." links. - if (mount(".", "/", NULL, MS_MOVE, NULL)) + // Overmount / with newdir and chroot into it + if (mount(".", "/", NULL, MS_MOVE, NULL)) { + // For example, fails when newroot is not a mountpoint bb_perror_msg_and_die("error moving root"); + } + // The chdir is needed to recalculate "." and ".." links xchroot("."); xchdir("/"); - // If a new console specified, redirect stdin/stdout/stderr to that. + // If a new console specified, redirect stdin/stdout/stderr to it if (console) { close(0); xopen(console, O_RDWR); @@ -109,7 +115,7 @@ xdup2(0, 2); } - // Exec real init. (This is why we must be pid 1.) + // Exec real init execv(argv[0], argv); - bb_perror_msg_and_die("bad init %s", argv[0]); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); } ------------------------------------------------------------------------ r26174 | vda | 2009-04-21 06:23:56 -0500 (Tue, 21 Apr 2009) | 6 lines Changed paths: M /trunk/busybox/shell/hush.c hush: speed up set_local_var function old new delta set_local_var 265 290 +25 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26173) +++ shell/hush.c (revision 26174) @@ -1266,16 +1266,16 @@ static int set_local_var(char *str, int flg_export, int flg_read_only) { struct variable *cur; - char *value; + char *eq_sign; int name_len; - value = strchr(str, '='); - if (!value) { /* not expected to ever happen? */ + eq_sign = strchr(str, '='); + if (!eq_sign) { /* not expected to ever happen? */ free(str); return -1; } - name_len = value - str + 1; /* including '=' */ + name_len = eq_sign - str + 1; /* including '=' */ cur = G.top_var; /* cannot be NULL (we have HUSH_VERSION and it's RO) */ while (1) { if (strncmp(cur->varstr, str, name_len) != 0) { @@ -1288,7 +1288,6 @@ continue; } /* We found an existing var with this name */ - *value = '\0'; if (cur->flg_read_only) { #if !BB_MMU if (!flg_read_only) @@ -1297,11 +1296,13 @@ free(str); return -1; } -//TODO: optimize out redundant unsetenv/putenv's? - debug_printf_env("%s: unsetenv '%s'\n", __func__, str); - unsetenv(str); /* just in case */ - *value = '='; - if (strcmp(cur->varstr, str) == 0) { + if (flg_export == -1) { + debug_printf_env("%s: unsetenv '%s'\n", __func__, str); + *eq_sign = '\0'; + unsetenv(str); + *eq_sign = '='; + } + if (strcmp(cur->varstr + name_len, eq_sign + 1) == 0) { free_and_exp: free(str); goto exp; ------------------------------------------------------------------------ r26173 | vda | 2009-04-21 06:09:40 -0500 (Tue, 21 Apr 2009) | 5 lines Changed paths: M /trunk/busybox/archival/bbunzip.c M /trunk/busybox/archival/bzip2.c M /trunk/busybox/archival/cpio.c M /trunk/busybox/archival/gzip.c M /trunk/busybox/archival/libunarchive/decompress_bunzip2.c M /trunk/busybox/archival/libunarchive/decompress_uncompress.c M /trunk/busybox/archival/libunarchive/decompress_unlzma.c M /trunk/busybox/archival/libunarchive/decompress_unzip.c M /trunk/busybox/archival/libunarchive/get_header_tar.c M /trunk/busybox/archival/libunarchive/open_transformer.c M /trunk/busybox/archival/rpm.c M /trunk/busybox/archival/tar.c M /trunk/busybox/coreutils/chmod.c M /trunk/busybox/coreutils/chown.c M /trunk/busybox/coreutils/date.c M /trunk/busybox/coreutils/df.c M /trunk/busybox/coreutils/du.c M /trunk/busybox/coreutils/expand.c M /trunk/busybox/coreutils/id.c M /trunk/busybox/coreutils/install.c M /trunk/busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c M /trunk/busybox/coreutils/ls.c M /trunk/busybox/coreutils/mkdir.c M /trunk/busybox/coreutils/readlink.c M /trunk/busybox/coreutils/stat.c M /trunk/busybox/coreutils/tail.c M /trunk/busybox/coreutils/touch.c M /trunk/busybox/coreutils/tty.c M /trunk/busybox/coreutils/uname.c M /trunk/busybox/debianutils/run_parts.c M /trunk/busybox/debianutils/start_stop_daemon.c M /trunk/busybox/debianutils/which.c M /trunk/busybox/docs/autodocifier.pl M /trunk/busybox/docs/new-applet-HOWTO.txt M /trunk/busybox/editors/cmp.c M /trunk/busybox/editors/diff.c M /trunk/busybox/editors/vi.c M /trunk/busybox/findutils/find.c M /trunk/busybox/findutils/grep.c M /trunk/busybox/findutils/xargs.c M /trunk/busybox/include/applets.h M /trunk/busybox/include/libbb.h M /trunk/busybox/include/unarchive.h M /trunk/busybox/include/usage.h M /trunk/busybox/libbb/appletlib.c M /trunk/busybox/libbb/lineedit.c M /trunk/busybox/libbb/mtab_file.c M /trunk/busybox/libbb/procps.c M /trunk/busybox/libbb/read.c M /trunk/busybox/libbb/xconnect.c M /trunk/busybox/libbb/xfuncs_printf.c M /trunk/busybox/loginutils/chpasswd.c M /trunk/busybox/loginutils/login.c M /trunk/busybox/loginutils/su.c M /trunk/busybox/loginutils/sulogin.c M /trunk/busybox/mailutils/mime.c M /trunk/busybox/mailutils/popmaildir.c M /trunk/busybox/miscutils/crond.c M /trunk/busybox/miscutils/eject.c M /trunk/busybox/miscutils/hdparm.c M /trunk/busybox/miscutils/less.c M /trunk/busybox/modutils/insmod.c M /trunk/busybox/modutils/modprobe-small.c M /trunk/busybox/modutils/modprobe.c M /trunk/busybox/modutils/modutils.h M /trunk/busybox/networking/brctl.c M /trunk/busybox/networking/ftpd.c M /trunk/busybox/networking/httpd.c M /trunk/busybox/networking/ifconfig.c M /trunk/busybox/networking/ifupdown.c M /trunk/busybox/networking/ip.c M /trunk/busybox/networking/ipcalc.c M /trunk/busybox/networking/libiproute/iproute.c M /trunk/busybox/networking/nc.c M /trunk/busybox/networking/nc_bloaty.c M /trunk/busybox/networking/netstat.c M /trunk/busybox/networking/ping.c M /trunk/busybox/networking/telnetd.c M /trunk/busybox/networking/telnetd.ctrlSQ.patch M /trunk/busybox/networking/tftp.c M /trunk/busybox/networking/tunctl.c M /trunk/busybox/networking/udhcp/dhcpc.c M /trunk/busybox/networking/udhcp/dhcpc.h M /trunk/busybox/networking/udhcp/dhcpd.c M /trunk/busybox/networking/udhcp/files.c M /trunk/busybox/networking/wget.c M /trunk/busybox/procps/pidof.c M /trunk/busybox/procps/ps.c M /trunk/busybox/procps/top.c M /trunk/busybox/runit/chpst.c M /trunk/busybox/scripts/basic/fixdep.c M /trunk/busybox/scripts/kconfig/confdata.c M /trunk/busybox/selinux/setfiles.c M /trunk/busybox/shell/ash.c M /trunk/busybox/shell/hush.c M /trunk/busybox/sysklogd/syslogd.c M /trunk/busybox/testsuite/all_sourcecode.tests M /trunk/busybox/util-linux/acpid.c M /trunk/busybox/util-linux/fdisk.c M /trunk/busybox/util-linux/fsck_minix.c M /trunk/busybox/util-linux/hexdump.c M /trunk/busybox/util-linux/mount.c *: mass renaming of USE_XXXX to IF_XXXX and SKIP_XXXX to IF_NOT_XXXX - the second one was especially badly named. It was not skipping anything! ------------------------------------------------------------------------ Index: networking/wget.c =================================================================== --- networking/wget.c (revision 26172) +++ networking/wget.c (revision 26173) @@ -497,14 +497,14 @@ applet_long_options = wget_longopts; #endif /* server.allocated = target.allocated = NULL; */ - opt_complementary = "-1" USE_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); + opt_complementary = "-1" IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); opt = getopt32(argv, "csqO:P:Y:U:" /*ignored:*/ "t:T:", &fname_out, &dir_prefix, &proxy_flag, &user_agent, NULL, /* -t RETRIES */ NULL /* -T NETWORK_READ_TIMEOUT */ - USE_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) - USE_FEATURE_WGET_LONG_OPTIONS(, &post_data) + IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) + IF_FEATURE_WGET_LONG_OPTIONS(, &post_data) ); if (strcmp(proxy_flag, "off") == 0) { /* Use the proxy if necessary */ Index: networking/ip.c =================================================================== --- networking/ip.c (revision 26172) +++ networking/ip.c (revision 26173) @@ -76,18 +76,18 @@ int ip_main(int argc UNUSED_PARAM, char **argv) { static const char keywords[] ALIGN1 = - USE_FEATURE_IP_ADDRESS("address\0") - USE_FEATURE_IP_ROUTE("route\0") - USE_FEATURE_IP_LINK("link\0") - USE_FEATURE_IP_TUNNEL("tunnel\0" "tunl\0") - USE_FEATURE_IP_RULE("rule\0") + IF_FEATURE_IP_ADDRESS("address\0") + IF_FEATURE_IP_ROUTE("route\0") + IF_FEATURE_IP_LINK("link\0") + IF_FEATURE_IP_TUNNEL("tunnel\0" "tunl\0") + IF_FEATURE_IP_RULE("rule\0") ; enum { - USE_FEATURE_IP_ADDRESS(IP_addr,) - USE_FEATURE_IP_ROUTE(IP_route,) - USE_FEATURE_IP_LINK(IP_link,) - USE_FEATURE_IP_TUNNEL(IP_tunnel, IP_tunl,) - USE_FEATURE_IP_RULE(IP_rule,) + IF_FEATURE_IP_ADDRESS(IP_addr,) + IF_FEATURE_IP_ROUTE(IP_route,) + IF_FEATURE_IP_LINK(IP_link,) + IF_FEATURE_IP_TUNNEL(IP_tunnel, IP_tunl,) + IF_FEATURE_IP_RULE(IP_rule,) IP_none }; int (*ip_func)(char**) = ip_print_help; Index: networking/nc_bloaty.c =================================================================== --- networking/nc_bloaty.c (revision 26172) +++ networking/nc_bloaty.c (revision 26173) @@ -675,7 +675,7 @@ int nc_main(int argc, char **argv) { char *str_p, *str_s; - USE_NC_EXTRA(char *str_i, *str_o;) + IF_NC_EXTRA(char *str_i, *str_o;) char *themdotted = themdotted; /* gcc */ char **proggie; int x; @@ -711,10 +711,10 @@ // -g -G -t -r deleted, unimplemented -a deleted too opt_complementary = "?2:vv:w+"; /* max 2 params; -v is a counter; -w N */ - getopt32(argv, "hnp:s:uvw:" USE_NC_SERVER("l") - USE_NC_EXTRA("i:o:z"), + getopt32(argv, "hnp:s:uvw:" IF_NC_SERVER("l") + IF_NC_EXTRA("i:o:z"), &str_p, &str_s, &o_wait - USE_NC_EXTRA(, &str_i, &str_o, &o_verbose)); + IF_NC_EXTRA(, &str_i, &str_o, &o_verbose)); argv += optind; #if ENABLE_NC_EXTRA if (option_mask32 & OPT_i) /* line-interval time */ Index: networking/tftp.c =================================================================== --- networking/tftp.c (revision 26172) +++ networking/tftp.c (revision 26173) @@ -64,15 +64,15 @@ }; #if ENABLE_FEATURE_TFTP_GET && !ENABLE_FEATURE_TFTP_PUT -#define USE_GETPUT(...) +#define IF_GETPUT(...) #define CMD_GET(cmd) 1 #define CMD_PUT(cmd) 0 #elif !ENABLE_FEATURE_TFTP_GET && ENABLE_FEATURE_TFTP_PUT -#define USE_GETPUT(...) +#define IF_GETPUT(...) #define CMD_GET(cmd) 0 #define CMD_PUT(cmd) 1 #else -#define USE_GETPUT(...) __VA_ARGS__ +#define IF_GETPUT(...) __VA_ARGS__ #define CMD_GET(cmd) ((cmd) & TFTP_OPT_GET) #define CMD_PUT(cmd) ((cmd) & TFTP_OPT_PUT) #endif @@ -160,9 +160,9 @@ len_and_sockaddr *our_lsa, len_and_sockaddr *peer_lsa, const char *local_file - USE_TFTP(, const char *remote_file) - USE_FEATURE_TFTP_BLOCKSIZE(USE_TFTPD(, void *tsize)) - USE_FEATURE_TFTP_BLOCKSIZE(, int blksize)) + IF_TFTP(, const char *remote_file) + IF_FEATURE_TFTP_BLOCKSIZE(IF_TFTPD(, void *tsize)) + IF_FEATURE_TFTP_BLOCKSIZE(, int blksize)) { #if !ENABLE_TFTP #define remote_file NULL @@ -178,7 +178,7 @@ #define socket_fd (pfd[0].fd) int len; int send_len; - USE_FEATURE_TFTP_BLOCKSIZE(smallint want_option_ack = 0;) + IF_FEATURE_TFTP_BLOCKSIZE(smallint want_option_ack = 0;) smallint finished = 0; uint16_t opcode; uint16_t block_nr; @@ -564,19 +564,19 @@ #endif int result; int port; - USE_GETPUT(int opt;) + IF_GETPUT(int opt;) INIT_G(); /* -p or -g is mandatory, and they are mutually exclusive */ - opt_complementary = "" USE_FEATURE_TFTP_GET("g:") USE_FEATURE_TFTP_PUT("p:") - USE_GETPUT("g--p:p--g:"); + opt_complementary = "" IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:") + IF_GETPUT("g--p:p--g:"); - USE_GETPUT(opt =) getopt32(argv, - USE_FEATURE_TFTP_GET("g") USE_FEATURE_TFTP_PUT("p") - "l:r:" USE_FEATURE_TFTP_BLOCKSIZE("b:"), + IF_GETPUT(opt =) getopt32(argv, + IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p") + "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:"), &local_file, &remote_file - USE_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)); + IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)); argv += optind; #if ENABLE_FEATURE_TFTP_BLOCKSIZE @@ -614,8 +614,8 @@ result = tftp_protocol( NULL /*our_lsa*/, peer_lsa, local_file, remote_file - USE_FEATURE_TFTP_BLOCKSIZE(USE_TFTPD(, NULL /*tsize*/)) - USE_FEATURE_TFTP_BLOCKSIZE(, blksize) + IF_FEATURE_TFTP_BLOCKSIZE(IF_TFTPD(, NULL /*tsize*/)) + IF_FEATURE_TFTP_BLOCKSIZE(, blksize) ); if (result != EXIT_SUCCESS && NOT_LONE_DASH(local_file) && CMD_GET(opt)) { @@ -635,8 +635,8 @@ char *local_file, *mode; const char *error_msg; int opt, result, opcode; - USE_FEATURE_TFTP_BLOCKSIZE(int blksize = TFTP_BLKSIZE_DEFAULT;) - USE_FEATURE_TFTP_BLOCKSIZE(char *tsize = NULL;) + IF_FEATURE_TFTP_BLOCKSIZE(int blksize = TFTP_BLKSIZE_DEFAULT;) + IF_FEATURE_TFTP_BLOCKSIZE(char *tsize = NULL;) INIT_G(); @@ -667,9 +667,9 @@ opcode = ntohs(*(uint16_t*)block_buf); if (result < 4 || result >= sizeof(block_buf) || block_buf[result-1] != '\0' - || (USE_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */ - USE_GETPUT(&&) - USE_FEATURE_TFTP_GET(opcode != TFTP_WRQ) /* not upload */ + || (IF_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */ + IF_GETPUT(&&) + IF_FEATURE_TFTP_GET(opcode != TFTP_WRQ) /* not upload */ ) ) { goto err; @@ -711,9 +711,9 @@ error_msg = bb_msg_write_error; goto err; } - USE_GETPUT(option_mask32 |= TFTP_OPT_GET;) /* will receive file's data */ + IF_GETPUT(option_mask32 |= TFTP_OPT_GET;) /* will receive file's data */ } else { - USE_GETPUT(option_mask32 |= TFTP_OPT_PUT;) /* will send file's data */ + IF_GETPUT(option_mask32 |= TFTP_OPT_PUT;) /* will send file's data */ } /* NB: if error_pkt_str or error_pkt_reason is set up, @@ -724,9 +724,9 @@ /* tftp_protocol() will create new one, bound to particular local IP */ result = tftp_protocol( our_lsa, peer_lsa, - local_file USE_TFTP(, NULL /*remote_file*/) - USE_FEATURE_TFTP_BLOCKSIZE(, tsize) - USE_FEATURE_TFTP_BLOCKSIZE(, blksize) + local_file IF_TFTP(, NULL /*remote_file*/) + IF_FEATURE_TFTP_BLOCKSIZE(, tsize) + IF_FEATURE_TFTP_BLOCKSIZE(, blksize) ); return result; Index: networking/telnetd.ctrlSQ.patch =================================================================== --- networking/telnetd.ctrlSQ.patch (revision 26172) +++ networking/telnetd.ctrlSQ.patch (revision 26173) @@ -104,7 +104,7 @@ +#endif /* Even if !STANDALONE, we accept (and ignore) -i, thus people * don't need to guess whether it's ok to pass -i to us */ - opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"), + opt = getopt32(argv, "f:l:Ki" IF_FEATURE_TELNETD_STANDALONE("p:b:F"), @@ -475,7 +495,7 @@ FD_SET(ts->sockfd_read, &rdfdset); if (ts->size2 > 0) /* can write to socket */ Index: networking/ifupdown.c =================================================================== --- networking/ifupdown.c (revision 26172) +++ networking/ifupdown.c (revision 26173) @@ -87,7 +87,7 @@ struct mapping_defn_t *mappings; }; -#define OPTION_STR "anvf" USE_FEATURE_IFUPDOWN_MAPPING("m") "i:" +#define OPTION_STR "anvf" IF_FEATURE_IFUPDOWN_MAPPING("m") "i:" enum { OPT_do_all = 0x1, OPT_no_act = 0x2, Index: networking/libiproute/iproute.c =================================================================== --- networking/libiproute/iproute.c (revision 26172) +++ networking/libiproute/iproute.c (revision 26173) @@ -287,14 +287,14 @@ static int iproute_modify(int cmd, unsigned flags, char **argv) { static const char keywords[] ALIGN1 = - "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0") + "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0") "dev\0""oif\0""to\0""metric\0"; enum { ARG_src, ARG_via, ARG_mtu, PARM_lock, ARG_protocol, -USE_FEATURE_IP_RULE(ARG_table,) +IF_FEATURE_IP_RULE(ARG_table,) ARG_dev, ARG_oif, ARG_to, Index: networking/telnetd.c =================================================================== --- networking/telnetd.c (revision 26172) +++ networking/telnetd.c (revision 26173) @@ -201,8 +201,8 @@ static struct tsession * make_new_session( - USE_FEATURE_TELNETD_STANDALONE(int sock) - SKIP_FEATURE_TELNETD_STANDALONE(void) + IF_FEATURE_TELNETD_STANDALONE(int sock) + IF_NOT_FEATURE_TELNETD_STANDALONE(void) ) { const char *login_argv[2]; struct termios termbuf; @@ -437,9 +437,9 @@ #endif /* Even if !STANDALONE, we accept (and ignore) -i, thus people * don't need to guess whether it's ok to pass -i to us */ - opt = getopt32(argv, "f:l:Ki" USE_FEATURE_TELNETD_STANDALONE("p:b:F"), + opt = getopt32(argv, "f:l:Ki" IF_FEATURE_TELNETD_STANDALONE("p:b:F"), &issuefile, &loginpath - USE_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr)); + IF_FEATURE_TELNETD_STANDALONE(, &opt_portnbr, &opt_bindaddr)); if (!IS_INETD /*&& !re_execed*/) { /* inform that we start in standalone mode? * May be useful when people forget to give -i */ @@ -455,7 +455,7 @@ openlog(applet_name, LOG_PID, LOG_DAEMON); logmode = LOGMODE_SYSLOG; } - USE_FEATURE_TELNETD_STANDALONE( + IF_FEATURE_TELNETD_STANDALONE( if (opt & OPT_PORT) portnbr = xatou16(opt_portnbr); ); Index: networking/nc.c =================================================================== --- networking/nc.c (revision 26172) +++ networking/nc.c (revision 26173) @@ -29,11 +29,11 @@ int sfd = sfd; /* for gcc */ int cfd = 0; unsigned lport = 0; - SKIP_NC_SERVER(const) unsigned do_listen = 0; - SKIP_NC_EXTRA (const) unsigned wsecs = 0; - SKIP_NC_EXTRA (const) unsigned delay = 0; - SKIP_NC_EXTRA (const int execparam = 0;) - USE_NC_EXTRA (char **execparam = NULL;) + IF_NOT_NC_SERVER(const) unsigned do_listen = 0; + IF_NOT_NC_EXTRA (const) unsigned wsecs = 0; + IF_NOT_NC_EXTRA (const) unsigned delay = 0; + IF_NOT_NC_EXTRA (const int execparam = 0;) + IF_NC_EXTRA (char **execparam = NULL;) len_and_sockaddr *lsa; fd_set readfds, testfds; int opt; /* must be signed (getopt returns -1) */ @@ -42,24 +42,24 @@ /* getopt32 is _almost_ usable: ** it cannot handle "... -e prog -prog-opt" */ while ((opt = getopt(argc, argv, - "" USE_NC_SERVER("lp:") USE_NC_EXTRA("w:i:f:e:") )) > 0 + "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 ) { if (ENABLE_NC_SERVER && opt=='l') - USE_NC_SERVER(do_listen++); + IF_NC_SERVER(do_listen++); else if (ENABLE_NC_SERVER && opt=='p') - USE_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); + IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); else if (ENABLE_NC_EXTRA && opt=='w') - USE_NC_EXTRA( wsecs = xatou(optarg)); + IF_NC_EXTRA( wsecs = xatou(optarg)); else if (ENABLE_NC_EXTRA && opt=='i') - USE_NC_EXTRA( delay = xatou(optarg)); + IF_NC_EXTRA( delay = xatou(optarg)); else if (ENABLE_NC_EXTRA && opt=='f') - USE_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); + IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); else if (ENABLE_NC_EXTRA && opt=='e' && optind <= argc) { /* We cannot just 'break'. We should let getopt finish. ** Or else we won't be able to find where ** 'host' and 'port' params are ** (think "nc -w 60 host port -e prog"). */ - USE_NC_EXTRA( + IF_NC_EXTRA( char **p; // +2: one for progname (optarg) and one for NULL execparam = xzalloc(sizeof(char*) * (argc - optind + 2)); @@ -154,7 +154,7 @@ xmove_fd(cfd, 0); xdup2(0, 1); xdup2(0, 2); - USE_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) + IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) /* Don't print stuff or it will go over the wire.... */ _exit(127); } Index: networking/brctl.c =================================================================== --- networking/brctl.c (revision 26172) +++ networking/brctl.c (revision 26173) @@ -99,20 +99,20 @@ { static const char keywords[] ALIGN1 = "addbr\0" "delbr\0" "addif\0" "delif\0" - USE_FEATURE_BRCTL_FANCY( + IF_FEATURE_BRCTL_FANCY( "stp\0" "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" "setpathcost\0" "setportprio\0" "setbridgeprio\0" ) - USE_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); + IF_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif - USE_FEATURE_BRCTL_FANCY(, + IF_FEATURE_BRCTL_FANCY(, ARG_stp, ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio ) - USE_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) + IF_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) }; int fd; Index: networking/tunctl.c =================================================================== --- networking/tunctl.c (revision 26172) +++ networking/tunctl.c (revision 26173) @@ -48,9 +48,9 @@ }; opt_complementary = "=0:t--d:d--t"; // no arguments; t ^ d - opts = getopt32(argv, "f:t:d:" USE_FEATURE_TUNCTL_UG("u:g:b"), + opts = getopt32(argv, "f:t:d:" IF_FEATURE_TUNCTL_UG("u:g:b"), &opt_device, &opt_name, &opt_name - USE_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); + IF_FEATURE_TUNCTL_UG(, &opt_user, &opt_group)); // select device memset(&ifr, 0, sizeof(ifr)); Index: networking/netstat.c =================================================================== --- networking/netstat.c (revision 26172) +++ networking/netstat.c (revision 26173) @@ -18,15 +18,15 @@ #include "inet_common.h" #define NETSTAT_OPTS "laentuwx" \ - USE_ROUTE( "r") \ - USE_FEATURE_NETSTAT_WIDE("W") \ - USE_FEATURE_NETSTAT_PRG( "p") + IF_ROUTE( "r") \ + IF_FEATURE_NETSTAT_WIDE("W") \ + IF_FEATURE_NETSTAT_PRG( "p") enum { OPTBIT_KEEP_OLD = 7, - USE_ROUTE( OPTBIT_ROUTE,) - USE_FEATURE_NETSTAT_WIDE(OPTBIT_WIDE ,) - USE_FEATURE_NETSTAT_PRG( OPTBIT_PRG ,) + IF_ROUTE( OPTBIT_ROUTE,) + IF_FEATURE_NETSTAT_WIDE(OPTBIT_WIDE ,) + IF_FEATURE_NETSTAT_PRG( OPTBIT_PRG ,) OPT_sock_listen = 1 << 0, // l OPT_sock_all = 1 << 1, // a OPT_extended = 1 << 2, // e @@ -35,9 +35,9 @@ OPT_sock_udp = 1 << 5, // u OPT_sock_raw = 1 << 6, // w OPT_sock_unix = 1 << 7, // x - OPT_route = USE_ROUTE( (1 << OPTBIT_ROUTE)) + 0, // r - OPT_wide = USE_FEATURE_NETSTAT_WIDE((1 << OPTBIT_WIDE )) + 0, // W - OPT_prg = USE_FEATURE_NETSTAT_PRG( (1 << OPTBIT_PRG )) + 0, // p + OPT_route = IF_ROUTE( (1 << OPTBIT_ROUTE)) + 0, // r + OPT_wide = IF_FEATURE_NETSTAT_WIDE((1 << OPTBIT_WIDE )) + 0, // W + OPT_prg = IF_FEATURE_NETSTAT_PRG( (1 << OPTBIT_PRG )) + 0, // p }; #define NETSTAT_CONNECTED 0x01 Index: networking/udhcp/files.c =================================================================== --- networking/udhcp/files.c (revision 26172) +++ networking/udhcp/files.c (revision 26173) @@ -394,7 +394,7 @@ struct dhcpOfferedAddr lease; int64_t written_at, time_passed; int fd; - USE_UDHCP_DEBUG(unsigned i;) + IF_UDHCP_DEBUG(unsigned i;) fd = open_or_warn(file, O_RDONLY); if (fd < 0) @@ -410,7 +410,7 @@ if ((uint64_t)time_passed > 12 * 60 * 60) goto ret; - USE_UDHCP_DEBUG(i = 0;) + IF_UDHCP_DEBUG(i = 0;) while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { /* ADDME: what if it matches some static lease? */ uint32_t y = ntohl(lease.yiaddr); @@ -424,7 +424,7 @@ bb_error_msg("too many leases while loading %s", file); break; } - USE_UDHCP_DEBUG(i++;) + IF_UDHCP_DEBUG(i++;) } } DEBUG("Read %d leases", i); Index: networking/udhcp/dhcpc.c =================================================================== --- networking/udhcp/dhcpc.c (revision 26172) +++ networking/udhcp/dhcpc.c (revision 26173) @@ -133,7 +133,7 @@ { uint8_t *temp, *message; char *str_c, *str_V, *str_h, *str_F, *str_r; - USE_FEATURE_UDHCP_PORT(char *str_P;) + IF_FEATURE_UDHCP_PORT(char *str_P;) llist_t *list_O = NULL; int tryagain_timeout = 20; int discover_timeout = 3; @@ -175,8 +175,8 @@ "no-default-options\0" No_argument "o" "foreground\0" No_argument "f" "background\0" No_argument "b" - USE_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") - USE_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") + IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") + IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") ; #endif enum { @@ -204,33 +204,33 @@ /* The rest has variable bit positions, need to be clever */ OPTBIT_f = 20, USE_FOR_MMU( OPTBIT_b,) - USE_FEATURE_UDHCPC_ARPING(OPTBIT_a,) - USE_FEATURE_UDHCP_PORT( OPTBIT_P,) + IF_FEATURE_UDHCPC_ARPING(OPTBIT_a,) + IF_FEATURE_UDHCP_PORT( OPTBIT_P,) USE_FOR_MMU( OPT_b = 1 << OPTBIT_b,) - USE_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,) - USE_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) + IF_FEATURE_UDHCPC_ARPING(OPT_a = 1 << OPTBIT_a,) + IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) }; /* Default options. */ - USE_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) - USE_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) + IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) + IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) client_config.interface = "eth0"; client_config.script = DEFAULT_SCRIPT; /* Parse command line */ /* Cc: mutually exclusive; O: list; -T,-t,-A take numeric param */ opt_complementary = "c--C:C--c:O::T+:t+:A+"; - USE_GETOPT_LONG(applet_long_options = udhcpc_longopts;) + IF_GETOPT_LONG(applet_long_options = udhcpc_longopts;) opt = getopt32(argv, "c:CV:H:h:F:i:np:qRr:s:T:t:vSA:O:of" USE_FOR_MMU("b") - USE_FEATURE_UDHCPC_ARPING("a") - USE_FEATURE_UDHCP_PORT("P:") + IF_FEATURE_UDHCPC_ARPING("a") + IF_FEATURE_UDHCP_PORT("P:") , &str_c, &str_V, &str_h, &str_h, &str_F , &client_config.interface, &client_config.pidfile, &str_r /* i,p */ , &client_config.script /* s */ , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ , &list_O - USE_FEATURE_UDHCP_PORT(, &str_P) + IF_FEATURE_UDHCP_PORT(, &str_P) ); if (opt & OPT_c) client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0); Index: networking/udhcp/dhcpd.c =================================================================== --- networking/udhcp/dhcpd.c (revision 26172) +++ networking/udhcp/dhcpd.c (revision 26173) @@ -37,14 +37,14 @@ unsigned opt; struct option_set *option; struct dhcpOfferedAddr *lease, static_lease; - USE_FEATURE_UDHCP_PORT(char *str_P;) + IF_FEATURE_UDHCP_PORT(char *str_P;) #if ENABLE_FEATURE_UDHCP_PORT SERVER_PORT = 67; CLIENT_PORT = 68; #endif - opt = getopt32(argv, "fS" USE_FEATURE_UDHCP_PORT("P:", &str_P)); + opt = getopt32(argv, "fS" IF_FEATURE_UDHCP_PORT("P:", &str_P)); argv += optind; if (!(opt & 1)) { /* no -f */ bb_daemonize_or_rexec(0, argv); Index: networking/udhcp/dhcpc.h =================================================================== --- networking/udhcp/dhcpc.h (revision 26172) +++ networking/udhcp/dhcpc.h (revision 26173) @@ -10,7 +10,7 @@ /* TODO: combine flag fields into single "unsigned opt" */ /* (can be set directly to the result of getopt32) */ char no_default_options; /* Do not include default optins in request */ - USE_FEATURE_UDHCP_PORT(uint16_t port;) + IF_FEATURE_UDHCP_PORT(uint16_t port;) int ifindex; /* Index number of the interface to use */ uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ const char *interface; /* The name of the interface to use */ Index: networking/httpd.c =================================================================== --- networking/httpd.c (revision 26172) +++ networking/httpd.c (revision 26173) @@ -250,13 +250,13 @@ const char *found_moved_temporarily; Htaccess_IP *ip_a_d; /* config allow/deny lines */ - USE_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) - USE_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;) - USE_FEATURE_HTTPD_CGI(char *referer;) - USE_FEATURE_HTTPD_CGI(char *user_agent;) - USE_FEATURE_HTTPD_CGI(char *host;) - USE_FEATURE_HTTPD_CGI(char *http_accept;) - USE_FEATURE_HTTPD_CGI(char *http_accept_language;) + IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) + IF_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;) + IF_FEATURE_HTTPD_CGI(char *referer;) + IF_FEATURE_HTTPD_CGI(char *user_agent;) + IF_FEATURE_HTTPD_CGI(char *host;) + IF_FEATURE_HTTPD_CGI(char *http_accept;) + IF_FEATURE_HTTPD_CGI(char *http_accept_language;) off_t file_size; /* -1 - unknown */ #if ENABLE_FEATURE_HTTPD_RANGES @@ -326,7 +326,7 @@ #define proxy (G.proxy ) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ - USE_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ + IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ bind_addr_or_port = "80"; \ index_page = "index.html"; \ file_size = -1; \ @@ -1587,14 +1587,14 @@ while (1) { /* sz is rounded down to 64k */ ssize_t sz = MAXINT(ssize_t) - 0xffff; - USE_FEATURE_HTTPD_RANGES(if (sz > range_len) sz = range_len;) + IF_FEATURE_HTTPD_RANGES(if (sz > range_len) sz = range_len;) count = sendfile(STDOUT_FILENO, fd, &offset, sz); if (count < 0) { if (offset == range_start) break; /* fall back to read/write loop */ goto fin; } - USE_FEATURE_HTTPD_RANGES(range_len -= sz;) + IF_FEATURE_HTTPD_RANGES(range_len -= sz;) if (count == 0 || range_len == 0) log_and_exit(); } @@ -1602,16 +1602,16 @@ #endif while ((count = safe_read(fd, iobuf, IOBUF_SIZE)) > 0) { ssize_t n; - USE_FEATURE_HTTPD_RANGES(if (count > range_len) count = range_len;) + IF_FEATURE_HTTPD_RANGES(if (count > range_len) count = range_len;) n = full_write(STDOUT_FILENO, iobuf, count); if (count != n) break; - USE_FEATURE_HTTPD_RANGES(range_len -= count;) + IF_FEATURE_HTTPD_RANGES(range_len -= count;) if (range_len == 0) break; } if (count < 0) { - USE_FEATURE_HTTPD_USE_SENDFILE(fin:) + IF_FEATURE_HTTPD_USE_SENDFILE(fin:) if (verbose > 1) bb_perror_msg("error"); } @@ -1839,12 +1839,12 @@ /* Find end of URL and parse HTTP version, if any */ http_major_version = '0'; - USE_FEATURE_HTTPD_PROXY(http_minor_version = '0';) + IF_FEATURE_HTTPD_PROXY(http_minor_version = '0';) tptr = strchrnul(urlp, ' '); /* Is it " HTTP/"? */ if (tptr[0] && strncmp(tptr + 1, HTTP_200, 5) == 0) { http_major_version = tptr[6]; - USE_FEATURE_HTTPD_PROXY(http_minor_version = tptr[8];) + IF_FEATURE_HTTPD_PROXY(http_minor_version = tptr[8];) } *tptr = '\0'; @@ -2252,10 +2252,10 @@ c_opt_config_file = 0, d_opt_decode_url, h_opt_home_httpd, - USE_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,) - USE_FEATURE_HTTPD_BASIC_AUTH( r_opt_realm ,) - USE_FEATURE_HTTPD_AUTH_MD5( m_opt_md5 ,) - USE_FEATURE_HTTPD_SETUID( u_opt_setuid ,) + IF_FEATURE_HTTPD_ENCODE_URL_STR(e_opt_encode_url,) + IF_FEATURE_HTTPD_BASIC_AUTH( r_opt_realm ,) + IF_FEATURE_HTTPD_AUTH_MD5( m_opt_md5 ,) + IF_FEATURE_HTTPD_SETUID( u_opt_setuid ,) p_opt_port , p_opt_inetd , p_opt_foreground, @@ -2263,10 +2263,10 @@ OPT_CONFIG_FILE = 1 << c_opt_config_file, OPT_DECODE_URL = 1 << d_opt_decode_url, OPT_HOME_HTTPD = 1 << h_opt_home_httpd, - OPT_ENCODE_URL = USE_FEATURE_HTTPD_ENCODE_URL_STR((1 << e_opt_encode_url)) + 0, - OPT_REALM = USE_FEATURE_HTTPD_BASIC_AUTH( (1 << r_opt_realm )) + 0, - OPT_MD5 = USE_FEATURE_HTTPD_AUTH_MD5( (1 << m_opt_md5 )) + 0, - OPT_SETUID = USE_FEATURE_HTTPD_SETUID( (1 << u_opt_setuid )) + 0, + OPT_ENCODE_URL = IF_FEATURE_HTTPD_ENCODE_URL_STR((1 << e_opt_encode_url)) + 0, + OPT_REALM = IF_FEATURE_HTTPD_BASIC_AUTH( (1 << r_opt_realm )) + 0, + OPT_MD5 = IF_FEATURE_HTTPD_AUTH_MD5( (1 << m_opt_md5 )) + 0, + OPT_SETUID = IF_FEATURE_HTTPD_SETUID( (1 << u_opt_setuid )) + 0, OPT_PORT = 1 << p_opt_port, OPT_INETD = 1 << p_opt_inetd, OPT_FOREGROUND = 1 << p_opt_foreground, @@ -2280,10 +2280,10 @@ int server_socket = server_socket; /* for gcc */ unsigned opt; char *url_for_decode; - USE_FEATURE_HTTPD_ENCODE_URL_STR(const char *url_for_encode;) - USE_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;) - USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) - USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;) + IF_FEATURE_HTTPD_ENCODE_URL_STR(const char *url_for_encode;) + IF_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;) + IF_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) + IF_FEATURE_HTTPD_AUTH_MD5(const char *pass;) INIT_G(); @@ -2299,16 +2299,16 @@ * If user gives relative path in -h, * $SCRIPT_FILENAME will not be set. */ opt = getopt32(argv, "c:d:h:" - USE_FEATURE_HTTPD_ENCODE_URL_STR("e:") - USE_FEATURE_HTTPD_BASIC_AUTH("r:") - USE_FEATURE_HTTPD_AUTH_MD5("m:") - USE_FEATURE_HTTPD_SETUID("u:") + 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", &configFile, &url_for_decode, &home_httpd - USE_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) - USE_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) - USE_FEATURE_HTTPD_AUTH_MD5(, &pass) - USE_FEATURE_HTTPD_SETUID(, &s_ugid) + IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) + IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) + IF_FEATURE_HTTPD_AUTH_MD5(, &pass) + IF_FEATURE_HTTPD_SETUID(, &s_ugid) , &bind_addr_or_port , &verbose ); Index: networking/ifconfig.c =================================================================== --- networking/ifconfig.c (revision 26172) +++ networking/ifconfig.c (revision 26173) @@ -424,7 +424,7 @@ } else { /* A_CAST_HOST_COPY_IN_ETHER */ /* This is the "hw" arg case. */ smalluint hw_class= index_in_substrings("ether\0" - USE_FEATURE_HWIB("infiniband\0"), *argv) + 1; + IF_FEATURE_HWIB("infiniband\0"), *argv) + 1; if (!hw_class || !*++argv) bb_show_usage(); /*safe_strncpy(host, *argv, sizeof(host));*/ Index: networking/ipcalc.c =================================================================== --- networking/ipcalc.c (revision 26172) +++ networking/ipcalc.c (revision 26173) @@ -86,7 +86,7 @@ #if ENABLE_FEATURE_IPCALC_LONG_OPTIONS applet_long_options = ipcalc_longopts; #endif - opt = getopt32(argv, "mbn" USE_FEATURE_IPCALC_FANCY("phs")); + opt = getopt32(argv, "mbn" IF_FEATURE_IPCALC_FANCY("phs")); argc -= optind; argv += optind; if (opt & (BROADCAST | NETWORK | NETPREFIX)) { Index: networking/ping.c =================================================================== --- networking/ping.c (revision 26172) +++ networking/ping.c (revision 26173) @@ -224,7 +224,7 @@ /* full(er) version */ -#define OPT_STRING ("qvc:s:w:W:I:4" USE_PING6("6")) +#define OPT_STRING ("qvc:s:w:W:I:4" IF_PING6("6")) enum { OPT_QUIET = 1 << 0, OPT_VERBOSE = 1 << 1, Index: networking/ftpd.c =================================================================== --- networking/ftpd.c (revision 26172) +++ networking/ftpd.c (revision 26173) @@ -1103,9 +1103,9 @@ G.timeout = 2 * 60; opt_complementary = "t+:T+:vv"; #if BB_MMU - opts = getopt32(argv, "vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose); + opts = getopt32(argv, "vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose); #else - opts = getopt32(argv, "l1vS" USE_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose); + opts = getopt32(argv, "l1vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose); if (opts & (OPT_l|OPT_1)) { /* Our secret backdoor to ls */ /* TODO: pass -n too? */ Index: scripts/kconfig/confdata.c =================================================================== --- scripts/kconfig/confdata.c (revision 26172) +++ scripts/kconfig/confdata.c (revision 26173) @@ -458,8 +458,8 @@ fprintf(out_h, "#undef CONFIG_%s\n", sym->name); /* bbox */ fprintf(out_h, "#define ENABLE_%s 0\n", sym->name); - fprintf(out_h, "#define USE_%s(...)\n", sym->name); - fprintf(out_h, "#define SKIP_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define IF_%s(...)\n", sym->name); + fprintf(out_h, "#define IF_NOT_%s(...) __VA_ARGS__\n", sym->name); } break; case mod: @@ -473,8 +473,8 @@ fprintf(out_h, "#define CONFIG_%s 1\n", sym->name); /* bbox */ fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); - fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); - fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + fprintf(out_h, "#define IF_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name); } break; } @@ -505,8 +505,8 @@ fputs("\"\n", out_h); /* bbox */ fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); - fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); - fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + fprintf(out_h, "#define IF_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name); } break; case S_HEX: @@ -517,8 +517,8 @@ fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str); /* bbox */ fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); - fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); - fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + fprintf(out_h, "#define IF_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name); } break; } @@ -531,8 +531,8 @@ fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str); /* bbox */ fprintf(out_h, "#define ENABLE_%s 1\n", sym->name); - fprintf(out_h, "#define USE_%s(...) __VA_ARGS__\n", sym->name); - fprintf(out_h, "#define SKIP_%s(...)\n", sym->name); + fprintf(out_h, "#define IF_%s(...) __VA_ARGS__\n", sym->name); + fprintf(out_h, "#define IF_NOT_%s(...)\n", sym->name); } break; } Index: scripts/basic/fixdep.c =================================================================== --- scripts/basic/fixdep.c (revision 26172) +++ scripts/basic/fixdep.c (revision 26173) @@ -225,32 +225,36 @@ void parse_config_file(char *map, size_t len) { /* modified for bbox */ - char *end_4 = map + len - 4; /* 4 == length of "USE_" */ + char *end_3 = map + len - 3; /* 3 == length of "IF_" */ char *end_7 = map + len - 7; char *p = map; char *q; int off; - for (; p < end_4; p++) { + for (; p <= end_3; p++) { + /* Find next identifier's beginning */ + if (!(isalnum(*p) || *p == '_')) + continue; + + /* Check it */ if (p < end_7 && p[6] == '_') { if (!memcmp(p, "CONFIG", 6)) goto conf7; if (!memcmp(p, "ENABLE", 6)) goto conf7; + if (!memcmp(p, "IF_NOT", 6)) goto conf7; } - /* We have at least 5 chars: for() has - * "p < end-4", not "p <= end-4" - * therefore we don't need to check p <= end-5 here */ - if (p[4] == '_') - if (!memcmp(p, "SKIP", 4)) goto conf5; - /* Ehhh, gcc is too stupid to just compare it as 32bit int */ - if (p[0] == 'U') - if (!memcmp(p, "USE_", 4)) goto conf4; + /* we have at least 3 chars because of p <= end_3 */ + /*if (!memcmp(p, "IF_", 3)) goto conf3;*/ + if (p[0] == 'I' && p[1] == 'F' && p[2] == '_') goto conf3; + + /* This identifier is not interesting, skip it */ + while (p <= end_3 && (isalnum(*p) || *p == '_')) + p++; continue; - conf4: off = 4; - conf5: off = 5; + conf3: off = 3; conf7: off = 7; p += off; - for (q = p; q < end_4+4; q++) { + for (q = p; q < end_3+3; q++) { if (!(isalnum(*q) || *q == '_')) break; } Index: docs/autodocifier.pl =================================================================== --- docs/autodocifier.pl (revision 26172) +++ docs/autodocifier.pl (revision 26173) @@ -24,8 +24,8 @@ my $text = shift; for (;;) { my $text2 = $text; - $text =~ s/SKIP_\w+\(.*?"\s*\)//sxg; - $text =~ s/USE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg; + $text =~ s/IF_NOT_\w+\(.*?"\s*\)//sxg; + $text =~ s/IF_\w+\(\s*?(.*?)"\s*\)/$1"/sxg; $text =~ s/USAGE_\w+\(\s*?(.*?)"\s*\)/$1"/sxg; last if ( $text2 eq $text ); } Index: docs/new-applet-HOWTO.txt =================================================================== --- docs/new-applet-HOWTO.txt (revision 26172) +++ docs/new-applet-HOWTO.txt (revision 26173) @@ -162,7 +162,7 @@ Be sure to read the top of applets.h before adding your applet. /* all programs above here are alphabetically "less than" 'mu' */ - USE_MU(APPLET(mu, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) + IF_MU(APPLET(mu, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) /* all programs below here are alphabetically "greater than" 'mu' */ Index: archival/rpm.c =================================================================== --- archival/rpm.c (revision 26172) +++ archival/rpm.c (revision 26173) @@ -190,7 +190,7 @@ archive_handle_t *archive_handle; unsigned char magic[2]; #if BB_MMU - USE_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); + IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); enum { xformer_prog = 0 }; #else enum { xformer = 0 }; @@ -224,7 +224,7 @@ || magic[0] != 'B' || magic[1] != 'Z' ) { bb_error_msg_and_die("no gzip" - USE_FEATURE_SEAMLESS_BZ2("/bzip2") + IF_FEATURE_SEAMLESS_BZ2("/bzip2") " magic"); } #if BB_MMU Index: archival/bbunzip.c =================================================================== --- archival/bbunzip.c (revision 26172) +++ archival/bbunzip.c (revision 26173) @@ -30,11 +30,11 @@ int FAST_FUNC bbunpack(char **argv, char* (*make_new_name)(char *filename), - USE_DESKTOP(long long) int (*unpacker)(unpack_info_t *info) + IF_DESKTOP(long long) int (*unpacker)(unpack_info_t *info) ) { struct stat stat_buf; - USE_DESKTOP(long long) int status; + IF_DESKTOP(long long) int status; char *filename, *new_name; smallint exitcode = 0; unpack_info_t info; @@ -175,7 +175,7 @@ } static -USE_DESKTOP(long long) int unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) +IF_DESKTOP(long long) int unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) { return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO); } @@ -251,9 +251,9 @@ } static -USE_DESKTOP(long long) int unpack_gunzip(unpack_info_t *info) +IF_DESKTOP(long long) int unpack_gunzip(unpack_info_t *info) { - USE_DESKTOP(long long) int status = -1; + IF_DESKTOP(long long) int status = -1; /* do the decompression, and cleanup */ if (xread_char(STDIN_FILENO) == 0x1f) { @@ -325,7 +325,7 @@ } static -USE_DESKTOP(long long) int unpack_unlzma(unpack_info_t *info UNUSED_PARAM) +IF_DESKTOP(long long) int unpack_unlzma(unpack_info_t *info UNUSED_PARAM) { return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO); } @@ -360,9 +360,9 @@ } static -USE_DESKTOP(long long) int unpack_uncompress(unpack_info_t *info UNUSED_PARAM) +IF_DESKTOP(long long) int unpack_uncompress(unpack_info_t *info UNUSED_PARAM) { - USE_DESKTOP(long long) int status = -1; + IF_DESKTOP(long long) int status = -1; if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) { bb_error_msg("invalid magic"); Index: archival/gzip.c =================================================================== --- archival/gzip.c (revision 26172) +++ archival/gzip.c (revision 26173) @@ -2015,7 +2015,7 @@ } static -USE_DESKTOP(long long) int pack_gzip(unpack_info_t *info UNUSED_PARAM) +IF_DESKTOP(long long) int pack_gzip(unpack_info_t *info UNUSED_PARAM) { struct stat s; @@ -2050,7 +2050,7 @@ unsigned opt; /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ - opt = getopt32(argv, "cfv" USE_GUNZIP("dt") "q123456789n"); + opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "q123456789n"); #if ENABLE_GUNZIP /* gunzip_main may not be visible... */ if (opt & 0x18) // -d and/or -t return gunzip_main(argc, argv); Index: archival/tar.c =================================================================== --- archival/tar.c (revision 26172) +++ archival/tar.c (revision 26173) @@ -728,14 +728,14 @@ enum { OPTBIT_KEEP_OLD = 7, - USE_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) - USE_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,) - USE_FEATURE_SEAMLESS_BZ2( OPTBIT_BZIP2 ,) - USE_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,) - USE_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,) - USE_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,) - USE_FEATURE_SEAMLESS_GZ( OPTBIT_GZIP ,) - USE_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) + IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) + IF_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,) + IF_FEATURE_SEAMLESS_BZ2( OPTBIT_BZIP2 ,) + IF_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,) + IF_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,) + IF_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,) + IF_FEATURE_SEAMLESS_GZ( OPTBIT_GZIP ,) + IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) OPTBIT_NOPRESERVE_OWN, OPTBIT_NOPRESERVE_PERM, OPTBIT_NUMERIC_OWNER, @@ -747,14 +747,14 @@ OPT_P = 1 << 5, // p OPT_VERBOSE = 1 << 6, // v OPT_KEEP_OLD = 1 << 7, // k - OPT_CREATE = USE_FEATURE_TAR_CREATE( (1 << OPTBIT_CREATE )) + 0, // c - OPT_DEREFERENCE = USE_FEATURE_TAR_CREATE( (1 << OPTBIT_DEREFERENCE )) + 0, // h - OPT_BZIP2 = USE_FEATURE_SEAMLESS_BZ2( (1 << OPTBIT_BZIP2 )) + 0, // j - OPT_LZMA = USE_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA )) + 0, // a - OPT_INCLUDE_FROM = USE_FEATURE_TAR_FROM( (1 << OPTBIT_INCLUDE_FROM)) + 0, // T - OPT_EXCLUDE_FROM = USE_FEATURE_TAR_FROM( (1 << OPTBIT_EXCLUDE_FROM)) + 0, // X - OPT_GZIP = USE_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z - OPT_COMPRESS = USE_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z + OPT_CREATE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_CREATE )) + 0, // c + OPT_DEREFERENCE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_DEREFERENCE )) + 0, // h + OPT_BZIP2 = IF_FEATURE_SEAMLESS_BZ2( (1 << OPTBIT_BZIP2 )) + 0, // j + OPT_LZMA = IF_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA )) + 0, // a + OPT_INCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_INCLUDE_FROM)) + 0, // T + OPT_EXCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_EXCLUDE_FROM)) + 0, // X + OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z + OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z OPT_NOPRESERVE_OWN = 1 << OPTBIT_NOPRESERVE_OWN , // no-same-owner OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions OPT_NUMERIC_OWNER = 1 << OPTBIT_NUMERIC_OWNER, @@ -832,24 +832,24 @@ #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM "\xff::" // cumulative lists for --exclude #endif - USE_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd - USE_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive - SKIP_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive + IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd + IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive + IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive #if ENABLE_FEATURE_TAR_LONG_OPTIONS applet_long_options = tar_longopts; #endif opt = getopt32(argv, "txC:f:Opvk" - USE_FEATURE_TAR_CREATE( "ch" ) - USE_FEATURE_SEAMLESS_BZ2( "j" ) - USE_FEATURE_SEAMLESS_LZMA("a" ) - USE_FEATURE_TAR_FROM( "T:X:") - USE_FEATURE_SEAMLESS_GZ( "z" ) - USE_FEATURE_SEAMLESS_Z( "Z" ) + IF_FEATURE_TAR_CREATE( "ch" ) + IF_FEATURE_SEAMLESS_BZ2( "j" ) + IF_FEATURE_SEAMLESS_LZMA("a" ) + IF_FEATURE_TAR_FROM( "T:X:") + IF_FEATURE_SEAMLESS_GZ( "z" ) + IF_FEATURE_SEAMLESS_Z( "Z" ) , &base_dir // -C dir , &tar_filename // -f filename - USE_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T - USE_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X + IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T + IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM , &excludes // --exclude #endif Index: archival/bzip2.c =================================================================== --- archival/bzip2.c (revision 26172) +++ archival/bzip2.c (revision 26173) @@ -64,7 +64,7 @@ * total written bytes so far otherwise */ static -USE_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, void *wbuf) +IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, void *wbuf) { int n, n2, ret; @@ -98,13 +98,13 @@ if (rlen && strm->avail_in == 0) break; } - return 0 USE_DESKTOP( + strm->total_out ); + return 0 IF_DESKTOP( + strm->total_out ); } static -USE_DESKTOP(long long) int compressStream(unpack_info_t *info UNUSED_PARAM) +IF_DESKTOP(long long) int compressStream(unpack_info_t *info UNUSED_PARAM) { - USE_DESKTOP(long long) int total; + IF_DESKTOP(long long) int total; ssize_t count; bz_stream bzs; /* it's small */ #define strm (&bzs) @@ -163,7 +163,7 @@ opt_complementary = "s2"; /* -s means -2 (compatibility) */ /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ - opt = getopt32(argv, "cfv" USE_BUNZIP2("dt") "123456789qzs"); + opt = getopt32(argv, "cfv" IF_BUNZIP2("dt") "123456789qzs"); #if ENABLE_BUNZIP2 /* bunzip2_main may not be visible... */ if (opt & 0x18) // -d and/or -t return bunzip2_main(argc, argv); Index: archival/libunarchive/decompress_bunzip2.c =================================================================== --- archival/libunarchive/decompress_bunzip2.c (revision 26172) +++ archival/libunarchive/decompress_bunzip2.c (revision 26173) @@ -648,10 +648,10 @@ /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC unpack_bz2_stream(int src_fd, int dst_fd) { - USE_DESKTOP(long long total_written = 0;) + IF_DESKTOP(long long total_written = 0;) char *outbuf; bunzip_data *bd; int i; @@ -666,7 +666,7 @@ i = RETVAL_SHORT_WRITE; break; } - USE_DESKTOP(total_written += i;) + IF_DESKTOP(total_written += i;) } } @@ -686,10 +686,10 @@ dealloc_bunzip(bd); free(outbuf); - return i ? i : USE_DESKTOP(total_written) + 0; + return i ? i : IF_DESKTOP(total_written) + 0; } -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC unpack_bz2_stream_prime(int src_fd, int dst_fd) { unsigned char magic[2]; Index: archival/libunarchive/decompress_uncompress.c =================================================================== --- archival/libunarchive/decompress_uncompress.c (revision 26172) +++ archival/libunarchive/decompress_uncompress.c (revision 26173) @@ -72,11 +72,11 @@ * be stored in the compressed file. */ -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC unpack_Z_stream(int fd_in, int fd_out) { - USE_DESKTOP(long long total_written = 0;) - USE_DESKTOP(long long) int retval = -1; + IF_DESKTOP(long long total_written = 0;) + IF_DESKTOP(long long) int retval = -1; unsigned char *stackp; long code; int finchar; @@ -265,7 +265,7 @@ if (outpos >= OBUFSIZ) { full_write(fd_out, outbuf, outpos); //error check?? - USE_DESKTOP(total_written += outpos;) + IF_DESKTOP(total_written += outpos;) outpos = 0; } stackp += i; @@ -294,10 +294,10 @@ if (outpos > 0) { full_write(fd_out, outbuf, outpos); //error check?? - USE_DESKTOP(total_written += outpos;) + IF_DESKTOP(total_written += outpos;) } - retval = USE_DESKTOP(total_written) + 0; + retval = IF_DESKTOP(total_written) + 0; err: free(inbuf); free(outbuf); Index: archival/libunarchive/open_transformer.c =================================================================== --- archival/libunarchive/open_transformer.c (revision 26172) +++ archival/libunarchive/open_transformer.c (revision 26173) @@ -12,7 +12,7 @@ * in include/unarchive.h. On NOMMU, transformer is removed. */ void FAST_FUNC open_transformer(int fd, - USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), + IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd), const char *transform_prog) { struct fd_pair fd_pipe; Index: archival/libunarchive/decompress_unzip.c =================================================================== --- archival/libunarchive/decompress_unzip.c (revision 26172) +++ archival/libunarchive/decompress_unzip.c (revision 26173) @@ -970,10 +970,10 @@ /* Called from unpack_gz_stream() and inflate_unzip() */ -static USE_DESKTOP(long long) int +static IF_DESKTOP(long long) int inflate_unzip_internal(STATE_PARAM int in, int out) { - USE_DESKTOP(long long) int n = 0; + IF_DESKTOP(long long) int n = 0; ssize_t nwrote; /* Allocate all global buffers (for DYN_ALLOC option) */ @@ -1008,7 +1008,7 @@ n = -1; goto ret; } - USE_DESKTOP(n += nwrote;) + IF_DESKTOP(n += nwrote;) if (r == 0) break; } @@ -1033,10 +1033,10 @@ /* For unzip */ -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC inflate_unzip(inflate_unzip_result *res, off_t compr_size, int in, int out) { - USE_DESKTOP(long long) int n; + IF_DESKTOP(long long) int n; DECLARE_STATE; ALLOC_STATE; @@ -1181,11 +1181,11 @@ return 1; } -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC unpack_gz_stream_with_info(int in, int out, unpack_info_t *info) { uint32_t v32; - USE_DESKTOP(long long) int n; + IF_DESKTOP(long long) int n; DECLARE_STATE; n = 0; @@ -1245,7 +1245,7 @@ return n; } -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC unpack_gz_stream(int in, int out) { return unpack_gz_stream_with_info(in, out, NULL); Index: archival/libunarchive/decompress_unlzma.c =================================================================== --- archival/libunarchive/decompress_unlzma.c (revision 26172) +++ archival/libunarchive/decompress_unlzma.c (revision 26173) @@ -228,10 +228,10 @@ }; -USE_DESKTOP(long long) int FAST_FUNC +IF_DESKTOP(long long) int FAST_FUNC unpack_lzma_stream(int src_fd, int dst_fd) { - USE_DESKTOP(long long total_written = 0;) + IF_DESKTOP(long long total_written = 0;) lzma_header_t header; int lc, pb, lp; uint32_t pos_state_mask; @@ -330,7 +330,7 @@ global_pos += header.dict_size; if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size) goto bad; - USE_DESKTOP(total_written += header.dict_size;) + IF_DESKTOP(total_written += header.dict_size;) } #else len = 1; @@ -468,20 +468,20 @@ } len += LZMA_MATCH_MIN_LEN; - SKIP_FEATURE_LZMA_FAST(string:) + IF_NOT_FEATURE_LZMA_FAST(string:) do { pos = buffer_pos - rep0; while (pos >= header.dict_size) pos += header.dict_size; previous_byte = buffer[pos]; - SKIP_FEATURE_LZMA_FAST(one_byte2:) + IF_NOT_FEATURE_LZMA_FAST(one_byte2:) buffer[buffer_pos++] = previous_byte; if (buffer_pos == header.dict_size) { buffer_pos = 0; global_pos += header.dict_size; if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size) goto bad; - USE_DESKTOP(total_written += header.dict_size;) + IF_DESKTOP(total_written += header.dict_size;) } len--; } while (len != 0 && buffer_pos < header.dst_size); @@ -489,8 +489,8 @@ } { - SKIP_DESKTOP(int total_written = 0; /* success */) - USE_DESKTOP(total_written += buffer_pos;) + IF_NOT_DESKTOP(int total_written = 0; /* success */) + IF_DESKTOP(total_written += buffer_pos;) if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) { bad: total_written = -1; /* failure */ Index: archival/libunarchive/get_header_tar.c =================================================================== --- archival/libunarchive/get_header_tar.c (revision 26172) +++ archival/libunarchive/get_header_tar.c (revision 26173) @@ -144,8 +144,8 @@ // if (!archive_handle->ah_priv_inited) { // archive_handle->ah_priv_inited = 1; // p_end = 0; -// USE_FEATURE_TAR_GNU_EXTENSIONS(p_longname = NULL;) -// USE_FEATURE_TAR_GNU_EXTENSIONS(p_linkname = NULL;) +// IF_FEATURE_TAR_GNU_EXTENSIONS(p_longname = NULL;) +// IF_FEATURE_TAR_GNU_EXTENSIONS(p_linkname = NULL;) // } if (sizeof(tar) != 512) @@ -176,7 +176,7 @@ bb_error_msg_and_die("short read"); } if (i != 512) { - USE_FEATURE_TAR_AUTODETECT(goto autodetect;) + IF_FEATURE_TAR_AUTODETECT(goto autodetect;) goto short_read; } @@ -265,14 +265,14 @@ #if ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY sum = strtoul(tar.chksum, &cp, 8); if ((*cp && *cp != ' ') - || (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) + || (sum_u != sum IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) ) { bb_error_msg_and_die("invalid tar header checksum"); } #else /* This field does not need special treatment (getOctal) */ sum = xstrtoul(tar.chksum, 8); - if (sum_u != sum USE_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) { + if (sum_u != sum IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)) { bb_error_msg_and_die("invalid tar header checksum"); } #endif @@ -356,7 +356,7 @@ file_header->mode |= S_IFBLK; goto size0; case '5': - USE_FEATURE_TAR_OLDGNU_COMPATIBILITY(set_dir:) + IF_FEATURE_TAR_OLDGNU_COMPATIBILITY(set_dir:) file_header->mode |= S_IFDIR; goto size0; case '6': Index: archival/cpio.c =================================================================== --- archival/cpio.c (revision 26172) +++ archival/cpio.c (revision 26173) @@ -270,7 +270,7 @@ { archive_handle_t *archive_handle; char *cpio_filename; - USE_FEATURE_CPIO_O(const char *cpio_fmt = "";) + IF_FEATURE_CPIO_O(const char *cpio_fmt = "";) unsigned opt; #if ENABLE_GETOPT_LONG @@ -295,7 +295,7 @@ #if !ENABLE_FEATURE_CPIO_O opt = getopt32(argv, OPTION_STR, &cpio_filename); #else - opt = getopt32(argv, OPTION_STR "oH:" USE_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); + opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); if (opt & CPIO_OPT_PASSTHROUGH) { pid_t pid; struct fd_pair pp; Index: sysklogd/syslogd.c =================================================================== --- sysklogd/syslogd.c (revision 26172) +++ sysklogd/syslogd.c (revision 26173) @@ -66,7 +66,7 @@ /*int markInterval;*/ \ /* level of messages to be logged */ \ int logLevel; \ -USE_FEATURE_ROTATE_LOGFILE( \ +IF_FEATURE_ROTATE_LOGFILE( \ /* max size of file before rotation */ \ unsigned logFileSize; \ /* number of rotated message files */ \ @@ -74,12 +74,12 @@ unsigned curFileSize; \ smallint isRegular; \ ) \ -USE_FEATURE_REMOTE_LOG( \ +IF_FEATURE_REMOTE_LOG( \ /* udp socket for remote logging */ \ int remoteFD; \ len_and_sockaddr* remoteAddr; \ ) \ -USE_FEATURE_IPC_SYSLOG( \ +IF_FEATURE_IPC_SYSLOG( \ int shmid; /* ipc shared memory id */ \ int s_semid; /* ipc semaphore id */ \ int shm_size; \ @@ -153,41 +153,41 @@ OPTBIT_outfile, // -O OPTBIT_loglevel, // -l OPTBIT_small, // -S - USE_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s - USE_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b - USE_FEATURE_REMOTE_LOG( OPTBIT_remotelog ,) // -R - USE_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L - USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C - USE_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D + IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize ,) // -s + IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt ,) // -b + IF_FEATURE_REMOTE_LOG( OPTBIT_remotelog ,) // -R + IF_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L + IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C + IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D OPT_mark = 1 << OPTBIT_mark , OPT_nofork = 1 << OPTBIT_nofork , OPT_outfile = 1 << OPTBIT_outfile , OPT_loglevel = 1 << OPTBIT_loglevel, OPT_small = 1 << OPTBIT_small , - OPT_filesize = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, - OPT_rotatecnt = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, - OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remotelog )) + 0, - OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0, - OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, - OPT_dup = USE_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, + OPT_filesize = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize )) + 0, + OPT_rotatecnt = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt )) + 0, + OPT_remotelog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_remotelog )) + 0, + OPT_locallog = IF_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0, + OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, + OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, }; #define OPTION_STR "m:nO:l:S" \ - USE_FEATURE_ROTATE_LOGFILE("s:" ) \ - USE_FEATURE_ROTATE_LOGFILE("b:" ) \ - USE_FEATURE_REMOTE_LOG( "R:" ) \ - USE_FEATURE_REMOTE_LOG( "L" ) \ - USE_FEATURE_IPC_SYSLOG( "C::") \ - USE_FEATURE_SYSLOGD_DUP( "D" ) + IF_FEATURE_ROTATE_LOGFILE("s:" ) \ + IF_FEATURE_ROTATE_LOGFILE("b:" ) \ + IF_FEATURE_REMOTE_LOG( "R:" ) \ + IF_FEATURE_REMOTE_LOG( "L" ) \ + IF_FEATURE_IPC_SYSLOG( "C::") \ + IF_FEATURE_SYSLOGD_DUP( "D" ) #define OPTION_DECL *opt_m, *opt_l \ - USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \ - USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \ - USE_FEATURE_IPC_SYSLOG( ,*opt_C = NULL) + IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ + IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ + IF_FEATURE_IPC_SYSLOG( ,*opt_C = NULL) #define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \ - USE_FEATURE_ROTATE_LOGFILE(,&opt_s) \ - USE_FEATURE_ROTATE_LOGFILE(,&opt_b) \ - USE_FEATURE_REMOTE_LOG( ,&G.remoteAddrStr) \ - USE_FEATURE_IPC_SYSLOG( ,&opt_C) + IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ + IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ + IF_FEATURE_REMOTE_LOG( ,&G.remoteAddrStr) \ + IF_FEATURE_IPC_SYSLOG( ,&opt_C) /* circular buffer variables/structures */ Index: modutils/modutils.h =================================================================== --- modutils/modutils.h (revision 26172) +++ modutils/modutils.h (revision 26173) @@ -26,10 +26,10 @@ #define INSMOD_OPTS \ "vq" \ - USE_FEATURE_2_4_MODULES("sLo:fkx") \ - USE_FEATURE_INSMOD_LOAD_MAP("m") + IF_FEATURE_2_4_MODULES("sLo:fkx") \ + IF_FEATURE_INSMOD_LOAD_MAP("m") -#define INSMOD_ARGS USE_FEATURE_2_4_MODULES(, NULL) +#define INSMOD_ARGS IF_FEATURE_2_4_MODULES(, NULL) enum { INSMOD_OPT_VERBOSE = 0x0001, Index: modutils/modprobe.c =================================================================== --- modutils/modprobe.c (revision 26172) +++ modutils/modprobe.c (revision 26173) @@ -33,7 +33,7 @@ llist_t *deps; /* strings. modules we depend on */ }; -#define MODPROBE_OPTS "acdlnrt:VC:" USE_FEATURE_MODPROBE_BLACKLIST("b") +#define MODPROBE_OPTS "acdlnrt:VC:" IF_FEATURE_MODPROBE_BLACKLIST("b") enum { MODPROBE_OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ MODPROBE_OPT_DUMP_ONLY = (INSMOD_OPT_UNUSED << 1), /* c */ Index: modutils/insmod.c =================================================================== --- modutils/insmod.c (revision 26172) +++ modutils/insmod.c (revision 26173) @@ -24,7 +24,7 @@ * or in $MODPATH. */ - USE_FEATURE_2_4_MODULES( + IF_FEATURE_2_4_MODULES( getopt32(argv, INSMOD_OPTS INSMOD_ARGS); argv += optind - 1; ); Index: modutils/modprobe-small.c =================================================================== --- modutils/modprobe-small.c (revision 26172) +++ modutils/modprobe-small.c (revision 26173) @@ -679,7 +679,7 @@ { struct utsname uts; char applet0 = applet_name[0]; - USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) + IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) /* are we lsmod? -> just dump /proc/modules */ if ('l' == applet0) { @@ -773,8 +773,8 @@ len = MAXINT(ssize_t); map = xmalloc_xopen_read_close(*argv, &len); if (init_module(map, len, - USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "") - SKIP_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("") + IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "") + IF_NOT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("") ) != 0) bb_error_msg_and_die("can't insert '%s': %s", *argv, moderror(errno)); @@ -791,7 +791,7 @@ } while (*argv); if (ENABLE_FEATURE_CLEAN_UP) { - USE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) + IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) } return EXIT_SUCCESS; } Index: debianutils/which.c =================================================================== --- debianutils/which.c (revision 26172) +++ debianutils/which.c (revision 26173) @@ -15,13 +15,13 @@ int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int which_main(int argc UNUSED_PARAM, char **argv) { - USE_DESKTOP(int opt;) + IF_DESKTOP(int opt;) int status = EXIT_SUCCESS; char *path; char *p; opt_complementary = "-1"; /* at least one argument */ - USE_DESKTOP(opt =) getopt32(argv, "a"); + IF_DESKTOP(opt =) getopt32(argv, "a"); argv += optind; /* This matches what is seen on e.g. ubuntu. Index: debianutils/start_stop_daemon.c =================================================================== --- debianutils/start_stop_daemon.c (revision 26172) +++ debianutils/start_stop_daemon.c (revision 26173) @@ -347,13 +347,13 @@ /* -xa (at least one) is required if -S is given */ /* -q turns off -v */ opt_complementary = "K:S:K--S:S--K:m?p:K?xpun:S?xa" - USE_FEATURE_START_STOP_DAEMON_FANCY("q-v"); + IF_FEATURE_START_STOP_DAEMON_FANCY("q-v"); opt = getopt32(argv, "KSbqtma:n:s:u:c:x:p:" - USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), + IF_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile - USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) + IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) /* We accept and ignore -R / --retry */ - USE_FEATURE_START_STOP_DAEMON_FANCY(,NULL) + IF_FEATURE_START_STOP_DAEMON_FANCY(,NULL) ); if (opt & OPT_s) { @@ -366,7 +366,7 @@ if (!execname) /* in case -a is given and -x is not */ execname = startas; -// USE_FEATURE_START_STOP_DAEMON_FANCY( +// IF_FEATURE_START_STOP_DAEMON_FANCY( // if (retry_arg) // retries = xatoi_u(retry_arg); // ) Index: debianutils/run_parts.c =================================================================== --- debianutils/run_parts.c (revision 26172) +++ debianutils/run_parts.c (revision 26173) @@ -124,7 +124,7 @@ /* We require exactly one argument: the directory name */ /* We require exactly one argument: the directory name */ opt_complementary = "=1:a::"; - getopt32(argv, "ra:u:t"USE_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p); + getopt32(argv, "ra:u:t"IF_FEATURE_RUN_PARTS_FANCY("l"), &arg_list, &umask_p); umask(xstrtou_range(umask_p, 8, 0, 07777)); Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26172) +++ shell/hush.c (revision 26173) @@ -97,11 +97,11 @@ /* STANDALONE does not make sense, and won't compile */ # undef CONFIG_FEATURE_SH_STANDALONE # undef ENABLE_FEATURE_SH_STANDALONE -# undef USE_FEATURE_SH_STANDALONE -# define SKIP_FEATURE_SH_STANDALONE(...) __VA_ARGS__ +# undef IF_FEATURE_SH_STANDALONE +# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ # define ENABLE_FEATURE_SH_STANDALONE 0 -# define USE_FEATURE_SH_STANDALONE(...) -# define SKIP_FEATURE_SH_STANDALONE(...) __VA_ARGS__ +# define IF_FEATURE_SH_STANDALONE(...) +# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ #endif #if !ENABLE_HUSH_INTERACTIVE @@ -2443,11 +2443,11 @@ goto do_exec; } - sprintf(param_buf, "-$%x:%x:%x" USE_HUSH_LOOPS(":%x") + sprintf(param_buf, "-$%x:%x:%x" IF_HUSH_LOOPS(":%x") , (unsigned) G.root_pid , (unsigned) G.last_bg_pid , (unsigned) G.last_exitcode - USE_HUSH_LOOPS(, G.depth_of_loop) + IF_HUSH_LOOPS(, G.depth_of_loop) ); /* 1:hush 2:-$ : : : * 3:-c 4: 5: 6:NULL @@ -3386,7 +3386,7 @@ debug_printf_exec("run_pipe start: members:%d\n", pi->num_cmds); debug_enter(); - USE_HUSH_JOB(pi->pgrp = -1;) + IF_HUSH_JOB(pi->pgrp = -1;) pi->stopped_cmds = 0; command = &(pi->cmds[0]); argv_expanded = NULL; @@ -3821,7 +3821,7 @@ rcode = G.last_exitcode; /* Go through list of pipes, (maybe) executing them. */ - for (; pi; pi = USE_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) { + for (; pi; pi = IF_HUSH_LOOPS(rword == RES_DONE ? loop_top : ) pi->next) { if (G.flag_SIGINT) break; @@ -4773,7 +4773,7 @@ close(channel[0]); /* NB: close _first_, then move fd! */ xmove_fd(channel[1], 1); /* Prevent it from trying to handle ctrl-z etc */ - USE_HUSH_JOB(G.run_list_level = 1;) + IF_HUSH_JOB(G.run_list_level = 1;) #if BB_MMU reset_traps_to_defaults(); parse_and_run_string(s); @@ -5441,7 +5441,7 @@ nommu_addchr(&ctx.as_string, ch); is_ifs = strchr(G.ifs, ch); is_special = strchr("<>;&|(){}#'" /* special outside of "str" */ - "\\$\"" USE_HUSH_TICK("`") /* always special */ + "\\$\"" IF_HUSH_TICK("`") /* always special */ , ch); if (!is_special && !is_ifs) { /* ordinary char */ @@ -5832,7 +5832,7 @@ } /* Discard cached input, force prompt */ input->p = NULL; - USE_HUSH_INTERACTIVE(input->promptme = 1;) + IF_HUSH_INTERACTIVE(input->promptme = 1;) goto reset; } } Index: shell/ash.c =================================================================== --- shell/ash.c (revision 26172) +++ shell/ash.c (revision 26173) @@ -56,11 +56,11 @@ /* STANDALONE does not make sense, and won't compile */ #undef CONFIG_FEATURE_SH_STANDALONE #undef ENABLE_FEATURE_SH_STANDALONE -#undef USE_FEATURE_SH_STANDALONE -#undef SKIP_FEATURE_SH_STANDALONE(...) +#undef IF_FEATURE_SH_STANDALONE +#undef IF_NOT_FEATURE_SH_STANDALONE(...) #define ENABLE_FEATURE_SH_STANDALONE 0 -#define USE_FEATURE_SH_STANDALONE(...) -#define SKIP_FEATURE_SH_STANDALONE(...) __VA_ARGS__ +#define IF_FEATURE_SH_STANDALONE(...) +#define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ #endif #ifndef PIPE_BUF @@ -349,7 +349,7 @@ } while (0) #endif -static USE_ASH_OPTIMIZE_FOR_SIZE(inline) void +static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void int_on(void) { xbarrier(); @@ -358,7 +358,7 @@ } } #define INT_ON int_on() -static USE_ASH_OPTIMIZE_FOR_SIZE(inline) void +static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void force_int_on(void) { xbarrier(); @@ -4219,7 +4219,7 @@ static const char vstype[VSTYPE + 1][3] = { "", "}", "-", "+", "?", "=", "%", "%%", "#", "##" - USE_ASH_BASH_COMPAT(, ":", "/", "//") + IF_ASH_BASH_COMPAT(, ":", "/", "//") }; const char *p, *str; @@ -6069,9 +6069,9 @@ char *startp; char *loc; char *rmesc, *rmescend; - USE_ASH_BASH_COMPAT(char *repl = NULL;) - USE_ASH_BASH_COMPAT(char null = '\0';) - USE_ASH_BASH_COMPAT(int pos, len, orig_len;) + IF_ASH_BASH_COMPAT(char *repl = NULL;) + IF_ASH_BASH_COMPAT(char null = '\0';) + IF_ASH_BASH_COMPAT(int pos, len, orig_len;) int saveherefd = herefd; int amount, workloc, resetloc; int zero; @@ -6157,7 +6157,7 @@ * stack will need rebasing, and we'll need to remove our work * areas each time */ - USE_ASH_BASH_COMPAT(restart:) + IF_ASH_BASH_COMPAT(restart:) amount = expdest - ((char *)stackblock() + resetloc); STADJUST(-amount, expdest); @@ -7083,7 +7083,7 @@ static void -tryexec(USE_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) +tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp) { int repeated = 0; @@ -7155,13 +7155,13 @@ || (applet_no = find_applet_by_name(argv[0])) >= 0 #endif ) { - tryexec(USE_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp); + tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp); e = errno; } else { e = ENOENT; while ((cmdname = padvance(&path, argv[0])) != NULL) { if (--idx < 0 && pathopt == NULL) { - tryexec(USE_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); + tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); if (errno != ENOENT && errno != ENOTDIR) e = errno; } @@ -10789,7 +10789,7 @@ int parenlevel; /* levels of parens in arithmetic */ int dqvarnest; /* levels of variables expansion within double quotes */ - USE_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;) + IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;) #if __GNUC__ /* Avoid longjmp clobbering */ @@ -10895,7 +10895,7 @@ dblquote = 1; goto quotemark; case CENDQUOTE: - USE_ASH_BASH_COMPAT(bash_dollar_squote = 0;) + IF_ASH_BASH_COMPAT(bash_dollar_squote = 0;) if (eofmark != NULL && arinest == 0 && varnest == 0 ) { @@ -10994,7 +10994,7 @@ len = out - (char *)stackblock(); out = stackblock(); if (eofmark == NULL) { - if ((c == '>' || c == '<' USE_ASH_BASH_COMPAT( || c == 0x100 + '>')) + if ((c == '>' || c == '<' IF_ASH_BASH_COMPAT( || c == 0x100 + '>')) && quotef == 0 ) { if (isdigit_str9(out)) { @@ -11488,7 +11488,7 @@ startlinno = g_parsefile->linno; for (;;) { /* until token or start of word found */ c = pgetc_fast(); - if (c == ' ' || c == '\t' USE_ASH_ALIAS( || c == PEOA)) + if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA)) continue; if (c == '#') { @@ -12454,8 +12454,8 @@ rflag = 0; prompt = NULL; while ((i = nextopt("p:u:r" - USE_ASH_READ_TIMEOUT("t:") - USE_ASH_READ_NCHARS("n:s") + IF_ASH_READ_TIMEOUT("t:") + IF_ASH_READ_NCHARS("n:s") )) != '\0') { switch (i) { case 'p': Index: coreutils/uname.c =================================================================== --- coreutils/uname.c (revision 26172) +++ coreutils/uname.c (revision 26173) @@ -97,7 +97,7 @@ const unsigned short *delta; unsigned toprint; - USE_GETOPT_LONG(applet_long_options = longopts); + IF_GETOPT_LONG(applet_long_options = longopts); toprint = getopt32(argv, options); if (argv[optind]) { /* coreutils-6.9 compat */ Index: coreutils/libcoreutils/getopt_mk_fifo_nod.c =================================================================== --- coreutils/libcoreutils/getopt_mk_fifo_nod.c (revision 26172) +++ coreutils/libcoreutils/getopt_mk_fifo_nod.c (revision 26173) @@ -31,7 +31,7 @@ security_context_t scontext; #endif int opt; - opt = getopt32(argv, "m:" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); + opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { if (bb_parse_mode(smode, &mode)) umask(0); Index: coreutils/df.c =================================================================== --- coreutils/df.c (revision 26172) +++ coreutils/df.c (revision 26173) @@ -64,9 +64,9 @@ opt_complementary = "k-m:m-k"; #endif opt = getopt32(argv, "kP" - USE_FEATURE_DF_FANCY("aiB:") - USE_FEATURE_HUMAN_READABLE("hm") - USE_FEATURE_DF_FANCY(, &chp)); + IF_FEATURE_DF_FANCY("aiB:") + IF_FEATURE_HUMAN_READABLE("hm") + IF_FEATURE_DF_FANCY(, &chp)); if (opt & OPT_MEGA) df_disp_hr = 1024*1024; Index: coreutils/date.c =================================================================== --- coreutils/date.c (revision 26172) +++ coreutils/date.c (revision 26173) @@ -52,11 +52,11 @@ char *isofmt_arg = NULL; opt_complementary = "d--s:s--d" - USE_FEATURE_DATE_ISOFMT(":R--I:I--R"); + IF_FEATURE_DATE_ISOFMT(":R--I:I--R"); opt = getopt32(argv, "Rs:ud:r:" - USE_FEATURE_DATE_ISOFMT("I::D:"), + IF_FEATURE_DATE_ISOFMT("I::D:"), &date_str, &date_str, &filename - USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); + IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt)); argv += optind; maybe_set_utc(opt); Index: coreutils/readlink.c =================================================================== --- coreutils/readlink.c (revision 26172) +++ coreutils/readlink.c (revision 26173) @@ -16,14 +16,14 @@ char *fname; char pathbuf[PATH_MAX]; - USE_FEATURE_READLINK_FOLLOW( + IF_FEATURE_READLINK_FOLLOW( unsigned opt; /* We need exactly one non-option argument. */ opt_complementary = "=1"; opt = getopt32(argv, "f"); fname = argv[optind]; ) - SKIP_FEATURE_READLINK_FOLLOW( + IF_NOT_FEATURE_READLINK_FOLLOW( const unsigned opt = 0; if (argc != 2) bb_show_usage(); fname = argv[1]; Index: coreutils/chmod.c =================================================================== --- coreutils/chmod.c (revision 26172) +++ coreutils/chmod.c (revision 26173) @@ -20,10 +20,10 @@ #define OPT_RECURSE (option_mask32 & 1) -#define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 2) SKIP_DESKTOP(0)) -#define OPT_CHANGED (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0)) -#define OPT_QUIET (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0)) -#define OPT_STR "R" USE_DESKTOP("vcf") +#define OPT_VERBOSE (IF_DESKTOP(option_mask32 & 2) IF_NOT_DESKTOP(0)) +#define OPT_CHANGED (IF_DESKTOP(option_mask32 & 4) IF_NOT_DESKTOP(0)) +#define OPT_QUIET (IF_DESKTOP(option_mask32 & 8) IF_NOT_DESKTOP(0)) +#define OPT_STR "R" IF_DESKTOP("vcf") /* coreutils: * chmod never changes the permissions of symbolic links; the chmod Index: coreutils/install.c =================================================================== --- coreutils/install.c (revision 26172) +++ coreutils/install.c (revision 26173) @@ -101,12 +101,12 @@ #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS applet_long_options = install_longopts; #endif - opt_complementary = "s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z"); + opt_complementary = "s--d:d--s" IF_SELINUX(":Z--\xff:\xff--Z"); /* -c exists for backwards compatibility, it's needed */ /* -v is ignored ("print name of each created directory") */ /* -b is ignored ("make a backup of each existing destination file") */ - opts = getopt32(argv, "cvb" "Ddpsg:m:o:" USE_SELINUX("Z:"), - &gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext)); + opts = getopt32(argv, "cvb" "Ddpsg:m:o:" IF_SELINUX("Z:"), + &gid_str, &mode_str, &uid_str IF_SELINUX(, &scontext)); argc -= optind; argv += optind; Index: coreutils/stat.c =================================================================== --- coreutils/stat.c (revision 26172) +++ coreutils/stat.c (revision 26173) @@ -156,7 +156,7 @@ /* print statfs info */ static void print_statfs(char *pformat, const char m, const char *const filename, const void *data - USE_SELINUX(, security_context_t scontext)) + IF_SELINUX(, security_context_t scontext)) { const struct statfs *statfsbuf = data; if (m == 'n') { @@ -203,7 +203,7 @@ /* print stat info */ static void print_stat(char *pformat, const char m, const char *const filename, const void *data - USE_SELINUX(, security_context_t scontext)) + IF_SELINUX(, security_context_t scontext)) { #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) struct stat *statbuf = (struct stat *) data; @@ -306,9 +306,9 @@ } static void print_it(const char *masterformat, const char *filename, - void (*print_func) (char*, char, const char*, const void* USE_SELINUX(, security_context_t scontext)), + void (*print_func) (char*, char, const char*, const void* IF_SELINUX(, security_context_t scontext)), const void *data - USE_SELINUX(, security_context_t scontext) ) + IF_SELINUX(, security_context_t scontext) ) { /* Create a working copy of the format string */ char *format = xstrdup(masterformat); @@ -347,7 +347,7 @@ break; default: /* Completes "% " with specifier and printfs */ - print_func(dest, *p, filename, data USE_SELINUX(,scontext)); + print_func(dest, *p, filename, data IF_SELINUX(,scontext)); break; } } @@ -416,7 +416,7 @@ ); #endif /* SELINUX */ } - print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); + print_it(format, filename, print_statfs, &statfsbuf IF_SELINUX(, scontext)); #else /* FEATURE_STAT_FORMAT */ format = (option_mask32 & OPT_TERSE ? "%s %llx %lu " @@ -560,11 +560,11 @@ } #endif } - print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext)); + print_it(format, filename, print_stat, &statbuf IF_SELINUX(, scontext)); #else /* FEATURE_STAT_FORMAT */ if (option_mask32 & OPT_TERSE) { printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu" - SKIP_SELINUX("\n"), + IF_NOT_SELINUX("\n"), filename, (uintmax_t) (statbuf.st_size), (uintmax_t) statbuf.st_blocks, @@ -642,14 +642,14 @@ int stat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int stat_main(int argc, char **argv) { - USE_FEATURE_STAT_FORMAT(char *format = NULL;) + IF_FEATURE_STAT_FORMAT(char *format = NULL;) int i; int ok = 1; statfunc_ptr statfunc = do_stat; getopt32(argv, "ftL" - USE_SELINUX("Z") - USE_FEATURE_STAT_FORMAT("c:", &format) + IF_SELINUX("Z") + IF_FEATURE_STAT_FORMAT("c:", &format) ); if (option_mask32 & OPT_FILESYS) /* -f */ @@ -663,7 +663,7 @@ } #endif /* ENABLE_SELINUX */ for (i = optind; i < argc; ++i) - ok &= statfunc(argv[i] USE_FEATURE_STAT_FORMAT(, format)); + ok &= statfunc(argv[i] IF_FEATURE_STAT_FORMAT(, format)); return (ok ? EXIT_SUCCESS : EXIT_FAILURE); } Index: coreutils/chown.c =================================================================== --- coreutils/chown.c (revision 26172) +++ coreutils/chown.c (revision 26173) @@ -16,13 +16,13 @@ /* This is a NOEXEC applet. Be very careful! */ -#define OPT_STR ("Rh" USE_DESKTOP("vcfLHP")) +#define OPT_STR ("Rh" IF_DESKTOP("vcfLHP")) #define BIT_RECURSE 1 #define OPT_RECURSE (opt & 1) #define OPT_NODEREF (opt & 2) -#define OPT_VERBOSE (USE_DESKTOP(opt & 0x04) SKIP_DESKTOP(0)) -#define OPT_CHANGED (USE_DESKTOP(opt & 0x08) SKIP_DESKTOP(0)) -#define OPT_QUIET (USE_DESKTOP(opt & 0x10) SKIP_DESKTOP(0)) +#define OPT_VERBOSE (IF_DESKTOP(opt & 0x04) IF_NOT_DESKTOP(0)) +#define OPT_CHANGED (IF_DESKTOP(opt & 0x08) IF_NOT_DESKTOP(0)) +#define OPT_QUIET (IF_DESKTOP(opt & 0x10) IF_NOT_DESKTOP(0)) /* POSIX options * -L traverse every symbolic link to a directory encountered * -H if a command line argument is a symbolic link to a directory, traverse it @@ -32,10 +32,10 @@ * The last option specified shall determine the behavior of the utility." */ /* -L */ #define BIT_TRAVERSE 0x20 -#define OPT_TRAVERSE (USE_DESKTOP(opt & BIT_TRAVERSE) SKIP_DESKTOP(0)) +#define OPT_TRAVERSE (IF_DESKTOP(opt & BIT_TRAVERSE) IF_NOT_DESKTOP(0)) /* -H or -L */ #define BIT_TRAVERSE_TOP (0x20|0x40) -#define OPT_TRAVERSE_TOP (USE_DESKTOP(opt & BIT_TRAVERSE_TOP) SKIP_DESKTOP(0)) +#define OPT_TRAVERSE_TOP (IF_DESKTOP(opt & BIT_TRAVERSE_TOP) IF_NOT_DESKTOP(0)) typedef int (*chown_fptr)(const char *, uid_t, gid_t); @@ -85,7 +85,7 @@ /* This matches coreutils behavior (almost - see below) */ if (OPT_NODEREF /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */ - USE_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE) + IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE) ) { param.chown_func = lchown; } Index: coreutils/tail.c =================================================================== --- coreutils/tail.c (revision 26172) +++ coreutils/tail.c (revision 26173) @@ -110,9 +110,9 @@ } #endif - USE_FEATURE_FANCY_TAIL(opt_complementary = "s+";) /* -s N */ - opt = getopt32(argv, "fc:n:" USE_FEATURE_FANCY_TAIL("qs:v"), - &str_c, &str_n USE_FEATURE_FANCY_TAIL(,&sleep_period)); + IF_FEATURE_FANCY_TAIL(opt_complementary = "s+";) /* -s N */ + opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:v"), + &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period)); #define FOLLOW (opt & 0x1) #define COUNT_BYTES (opt & 0x2) //if (opt & 0x1) // -f Index: coreutils/mkdir.c =================================================================== --- coreutils/mkdir.c (revision 26172) +++ coreutils/mkdir.c (revision 26173) @@ -48,7 +48,7 @@ #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS applet_long_options = mkdir_longopts; #endif - opt = getopt32(argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); + opt = getopt32(argv, "m:p" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { mode = 0777; if (!bb_parse_mode(smode, &mode)) { Index: coreutils/du.c =================================================================== --- coreutils/du.c (revision 26172) +++ coreutils/du.c (revision 26173) @@ -155,13 +155,13 @@ unsigned opt; #if ENABLE_FEATURE_HUMAN_READABLE - USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) - SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) + IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) + IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ G.disp_hr = 512; #else - USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;) - /* SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ + IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;) + /* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ #endif G.max_print_depth = INT_MAX; Index: coreutils/ls.c =================================================================== --- coreutils/ls.c (revision 26172) +++ coreutils/ls.c (revision 26173) @@ -46,12 +46,12 @@ */ # undef CONFIG_FEATURE_LS_TIMESTAMPS # undef ENABLE_FEATURE_LS_TIMESTAMPS -# undef USE_FEATURE_LS_TIMESTAMPS -# undef SKIP_FEATURE_LS_TIMESTAMPS +# undef IF_FEATURE_LS_TIMESTAMPS +# undef IF_NOT_FEATURE_LS_TIMESTAMPS # define CONFIG_FEATURE_LS_TIMESTAMPS 1 # define ENABLE_FEATURE_LS_TIMESTAMPS 1 -# define USE_FEATURE_LS_TIMESTAMPS(...) __VA_ARGS__ -# define SKIP_FEATURE_LS_TIMESTAMPS(...) +# define IF_FEATURE_LS_TIMESTAMPS(...) __VA_ARGS__ +# define IF_NOT_FEATURE_LS_TIMESTAMPS(...) #endif @@ -138,15 +138,15 @@ /* "[-]e", I think we made this one up */ static const char ls_options[] ALIGN1 = "Cadil1gnsxQAk" /* 13 opts, total 13 */ - USE_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ - USE_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ - USE_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ - USE_FEATURE_LS_FOLLOWLINKS("L") /* 1, 24 */ - USE_FEATURE_LS_RECURSIVE("R") /* 1, 25 */ - USE_FEATURE_HUMAN_READABLE("h") /* 1, 26 */ - USE_SELINUX("K") /* 1, 27 */ - USE_SELINUX("Z") /* 1, 28 */ - USE_FEATURE_AUTOWIDTH("T:w:") /* 2, 30 */ + IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ + IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ + IF_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ + IF_FEATURE_LS_FOLLOWLINKS("L") /* 1, 24 */ + IF_FEATURE_LS_RECURSIVE("R") /* 1, 25 */ + IF_FEATURE_HUMAN_READABLE("h") /* 1, 26 */ + IF_SELINUX("K") /* 1, 27 */ + IF_SELINUX("Z") /* 1, 28 */ + IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 30 */ ; enum { //OPT_C = (1 << 0), @@ -232,7 +232,7 @@ const char *fullname; /* the dir entry name */ int allocated; struct stat dstat; /* the file stat info */ - USE_SELINUX(security_context_t sid;) + IF_SELINUX(security_context_t sid;) struct dnode *next; /* point at the next node */ }; @@ -277,9 +277,9 @@ /* memset: we have to zero it out because of NOEXEC */ #define INIT_G() do { \ memset(&G, 0, sizeof(G)); \ - USE_FEATURE_AUTOWIDTH(tabstops = COLUMN_GAP;) \ - USE_FEATURE_AUTOWIDTH(terminal_width = TERMINAL_WIDTH;) \ - USE_FEATURE_LS_TIMESTAMPS(time(¤t_time_t);) \ + IF_FEATURE_AUTOWIDTH(tabstops = COLUMN_GAP;) \ + IF_FEATURE_AUTOWIDTH(terminal_width = TERMINAL_WIDTH;) \ + IF_FEATURE_LS_TIMESTAMPS(time(¤t_time_t);) \ } while (0) @@ -302,7 +302,7 @@ { struct stat dstat; struct dnode *cur; - USE_SELINUX(security_context_t sid = NULL;) + IF_SELINUX(security_context_t sid = NULL;) if ((all_fmt & FOLLOW_LINKS) || force_follow) { #if ENABLE_SELINUX @@ -332,7 +332,7 @@ cur->fullname = fullname; cur->name = name; cur->dstat = dstat; - USE_SELINUX(cur->sid = sid;) + IF_SELINUX(cur->sid = sid;) return cur; } @@ -570,7 +570,7 @@ column_width = len; } column_width += tabstops + - USE_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + ) + IF_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + ) ((all_fmt & LIST_INO) ? 8 : 0) + ((all_fmt & LIST_BLOCKS) ? 5 : 0); ncols = (int) (terminal_width / column_width); @@ -912,7 +912,7 @@ int dndirs; int i; /* need to initialize since --color has _an optional_ argument */ - USE_FEATURE_LS_COLOR(const char *color_opt = "always";) + IF_FEATURE_LS_COLOR(const char *color_opt = "always";) INIT_G(); @@ -927,13 +927,13 @@ #endif /* process options */ - USE_FEATURE_LS_COLOR(applet_long_options = ls_color_opt;) + IF_FEATURE_LS_COLOR(applet_long_options = ls_color_opt;) #if ENABLE_FEATURE_AUTOWIDTH opt_complementary = "T+:w+"; /* -T N, -w N */ opt = getopt32(argv, ls_options, &tabstops, &terminal_width - USE_FEATURE_LS_COLOR(, &color_opt)); + IF_FEATURE_LS_COLOR(, &color_opt)); #else - opt = getopt32(argv, ls_options USE_FEATURE_LS_COLOR(, &color_opt)); + opt = getopt32(argv, ls_options IF_FEATURE_LS_COLOR(, &color_opt)); #endif for (i = 0; opt_flags[i] != (1U<<31); i++) { if (opt & (1 << i)) { Index: coreutils/expand.c =================================================================== --- coreutils/expand.c (revision 26172) +++ coreutils/expand.c (revision 26173) @@ -132,10 +132,10 @@ #endif if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) { - USE_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts); + IF_FEATURE_EXPAND_LONG_OPTIONS(applet_long_options = expand_longopts); opt = getopt32(argv, "it:", &opt_t); } else { - USE_FEATURE_UNEXPAND_LONG_OPTIONS(applet_long_options = unexpand_longopts); + IF_FEATURE_UNEXPAND_LONG_OPTIONS(applet_long_options = unexpand_longopts); /* -t NUM sets also -a */ opt_complementary = "ta"; opt = getopt32(argv, "ft:a", &opt_t); @@ -157,9 +157,9 @@ } if (ENABLE_EXPAND && (!ENABLE_UNEXPAND || applet_name[0] == 'e')) - USE_EXPAND(expand(file, tab_size, opt)); + IF_EXPAND(expand(file, tab_size, opt)); else - USE_UNEXPAND(unexpand(file, tab_size, opt)); + IF_UNEXPAND(unexpand(file, tab_size, opt)); /* Check and close the file */ if (fclose_if_not_stdin(file)) { Index: coreutils/tty.c =================================================================== --- coreutils/tty.c (revision 26172) +++ coreutils/tty.c (revision 26173) @@ -13,17 +13,17 @@ #include "libbb.h" int tty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int tty_main(int argc, char **argv SKIP_INCLUDE_SUSv2(UNUSED_PARAM)) +int tty_main(int argc, char **argv IF_NOT_INCLUDE_SUSv2(UNUSED_PARAM)) { const char *s; - USE_INCLUDE_SUSv2(int silent;) /* Note: No longer relevant in SUSv3. */ + IF_INCLUDE_SUSv2(int silent;) /* Note: No longer relevant in SUSv3. */ int retval; xfunc_error_retval = 2; /* SUSv3 requires > 1 for error. */ - USE_INCLUDE_SUSv2(silent = getopt32(argv, "s");) - USE_INCLUDE_SUSv2(argc -= optind;) - SKIP_INCLUDE_SUSv2(argc -= 1;) + IF_INCLUDE_SUSv2(silent = getopt32(argv, "s");) + IF_INCLUDE_SUSv2(argc -= optind;) + IF_NOT_INCLUDE_SUSv2(argc -= 1;) /* gnu tty outputs a warning that it is ignoring all args. */ bb_warn_ignoring_args(argc); @@ -37,8 +37,8 @@ s = "not a tty"; retval = 1; } - USE_INCLUDE_SUSv2(if (!silent) puts(s);) - SKIP_INCLUDE_SUSv2(puts(s);) + IF_INCLUDE_SUSv2(if (!silent) puts(s);) + IF_NOT_INCLUDE_SUSv2(puts(s);) fflush_stdout_and_exit(retval); } Index: coreutils/touch.c =================================================================== --- coreutils/touch.c (revision 26172) +++ coreutils/touch.c (revision 26173) @@ -63,9 +63,9 @@ applet_long_options = longopts; #endif #endif - opts = getopt32(argv, "c" USE_DESKTOP("r:") + opts = getopt32(argv, "c" IF_DESKTOP("r:") /*ignored:*/ "fma" - USE_DESKTOP(, &reference_file)); + IF_DESKTOP(, &reference_file)); opts &= 1; /* only -c bit is left */ argv += optind; Index: coreutils/id.c =================================================================== --- coreutils/id.c (revision 26172) +++ coreutils/id.c (revision 26173) @@ -119,8 +119,8 @@ /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ /* Don't allow more than one username */ opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" - USE_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); - opt = getopt32(argv, "rnugG" USE_SELINUX("Z")); + IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); + opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); username = argv[optind]; if (username) { Index: libbb/procps.c =================================================================== --- libbb/procps.c (revision 26172) +++ libbb/procps.c (revision 26173) @@ -111,7 +111,7 @@ { closedir(sp->dir); free(sp->argv0); - USE_SELINUX(free(sp->context);) + IF_SELINUX(free(sp->context);) free(sp); } Index: libbb/read.c =================================================================== --- libbb/read.c (revision 26172) +++ libbb/read.c (revision 26173) @@ -315,7 +315,7 @@ char *sfx; int fd; #if BB_MMU - USE_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); + IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); enum { xformer_prog = 0 }; #else enum { xformer = 0 }; @@ -352,7 +352,7 @@ || magic[0] != 'B' || magic[1] != 'Z' ) { bb_error_msg_and_die("no gzip" - USE_FEATURE_SEAMLESS_BZ2("/bzip2") + IF_FEATURE_SEAMLESS_BZ2("/bzip2") " magic"); } #if BB_MMU Index: libbb/xfuncs_printf.c =================================================================== --- libbb/xfuncs_printf.c (revision 26172) +++ libbb/xfuncs_printf.c (revision 26173) @@ -420,7 +420,7 @@ const char *s = "INET"; if (domain == AF_PACKET) s = "PACKET"; if (domain == AF_NETLINK) s = "NETLINK"; -USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) +IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) bb_perror_msg_and_die("socket(AF_%s)", s); #else bb_perror_msg_and_die("socket"); Index: libbb/lineedit.c =================================================================== --- libbb/lineedit.c (revision 26172) +++ libbb/lineedit.c (revision 26173) @@ -62,10 +62,10 @@ #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) -#define USE_FEATURE_GETUSERNAME_AND_HOMEDIR(...) +#define IF_FEATURE_GETUSERNAME_AND_HOMEDIR(...) #if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR -#undef USE_FEATURE_GETUSERNAME_AND_HOMEDIR -#define USE_FEATURE_GETUSERNAME_AND_HOMEDIR(...) __VA_ARGS__ +#undef IF_FEATURE_GETUSERNAME_AND_HOMEDIR +#define IF_FEATURE_GETUSERNAME_AND_HOMEDIR(...) __VA_ARGS__ #endif enum { @@ -152,8 +152,8 @@ (*(struct lineedit_statics**)&lineedit_ptr_to_statics) = xzalloc(sizeof(S)); \ barrier(); \ cmdedit_termw = 80; \ - USE_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \ - USE_FEATURE_GETUSERNAME_AND_HOMEDIR(home_pwd_buf = (char*)null_str;) \ + IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \ + IF_FEATURE_GETUSERNAME_AND_HOMEDIR(home_pwd_buf = (char*)null_str;) \ } while (0) static void deinit_S(void) { @@ -1160,7 +1160,7 @@ if ((state->flags & SAVE_HISTORY) && state->hist_file) save_history(str); #endif - USE_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) + IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) } #else /* MAX_HISTORY == 0 */ @@ -1442,7 +1442,7 @@ /* leave out the "vi-mode"-only case labels if vi editing isn't * configured. */ -#define vi_case(caselabel) USE_FEATURE_EDITING(case caselabel) +#define vi_case(caselabel) IF_FEATURE_EDITING(case caselabel) /* convert uppercase ascii to equivalent control char, for readability */ #undef CTRL Index: libbb/xconnect.c =================================================================== --- libbb/xconnect.c (revision 26172) +++ libbb/xconnect.c (revision 26173) @@ -151,7 +151,7 @@ * port: if neither of above specifies port # */ static len_and_sockaddr* str2sockaddr( const char *host, int port, -USE_FEATURE_IPV6(sa_family_t af,) +IF_FEATURE_IPV6(sa_family_t af,) int ai_flags) { int rc; @@ -269,9 +269,9 @@ } #undef xsocket_type -int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int family,) int sock_type) +int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, IF_FEATURE_IPV6(int family,) int sock_type) { - SKIP_FEATURE_IPV6(enum { family = AF_INET };) + IF_NOT_FEATURE_IPV6(enum { family = AF_INET };) len_and_sockaddr *lsa; int fd; int len; @@ -303,7 +303,7 @@ int FAST_FUNC xsocket_stream(len_and_sockaddr **lsap) { - return xsocket_type(lsap, USE_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM); + return xsocket_type(lsap, IF_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM); } static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) @@ -316,7 +316,7 @@ /* user specified bind addr dictates family */ fd = xsocket(lsa->u.sa.sa_family, sock_type, 0); } else { - fd = xsocket_type(&lsa, USE_FEATURE_IPV6(AF_UNSPEC,) sock_type); + fd = xsocket_type(&lsa, IF_FEATURE_IPV6(AF_UNSPEC,) sock_type); set_nport(lsa, htons(port)); } setsockopt_reuseaddr(fd); Index: libbb/mtab_file.c =================================================================== --- libbb/mtab_file.c (revision 26172) +++ libbb/mtab_file.c (revision 26173) @@ -12,4 +12,4 @@ /* Busybox mount uses either /proc/mounts or /etc/mtab to * get the list of currently mounted filesystems */ const char bb_path_mtab_file[] ALIGN1 = -USE_FEATURE_MTAB_SUPPORT("/etc/mtab")SKIP_FEATURE_MTAB_SUPPORT("/proc/mounts"); +IF_FEATURE_MTAB_SUPPORT("/etc/mtab")IF_NOT_FEATURE_MTAB_SUPPORT("/proc/mounts"); Index: libbb/appletlib.c =================================================================== --- libbb/appletlib.c (revision 26172) +++ libbb/appletlib.c (revision 26173) @@ -55,8 +55,8 @@ #ifdef SINGLE_APPLET_MAIN #undef ENABLE_FEATURE_INDIVIDUAL #define ENABLE_FEATURE_INDIVIDUAL 1 -#undef USE_FEATURE_INDIVIDUAL -#define USE_FEATURE_INDIVIDUAL(...) __VA_ARGS__ +#undef IF_FEATURE_INDIVIDUAL +#define IF_FEATURE_INDIVIDUAL(...) __VA_ARGS__ #endif @@ -179,10 +179,10 @@ void lbb_prepare(const char *applet - USE_FEATURE_INDIVIDUAL(, char **argv)) + IF_FEATURE_INDIVIDUAL(, char **argv)) MAIN_EXTERNALLY_VISIBLE; void lbb_prepare(const char *applet - USE_FEATURE_INDIVIDUAL(, char **argv)) + IF_FEATURE_INDIVIDUAL(, char **argv)) { #ifdef __GLIBC__ (*(int **)&bb_errno) = __errno_location(); @@ -224,7 +224,7 @@ /* If not built as a single-applet executable... */ #if !defined(SINGLE_APPLET_MAIN) -USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ +IF_FEATURE_SUID(static uid_t ruid;) /* real uid */ #if ENABLE_FEATURE_SUID_CONFIG @@ -500,7 +500,7 @@ #else static inline void parse_config_file(void) { - USE_FEATURE_SUID(ruid = getuid();) + IF_FEATURE_SUID(ruid = getuid();) } #endif /* FEATURE_SUID_CONFIG */ @@ -754,10 +754,10 @@ #if defined(SINGLE_APPLET_MAIN) /* Only one applet is selected by the user! */ /* applet_names in this case is just "applet\0\0" */ - lbb_prepare(applet_names USE_FEATURE_INDIVIDUAL(, argv)); + lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv)); return SINGLE_APPLET_MAIN(argc, argv); #else - lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv)); + lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); #if !BB_MMU /* NOMMU re-exec trick sets high-order bit in first byte of name */ Index: miscutils/hdparm.c =================================================================== --- miscutils/hdparm.c (revision 26172) +++ miscutils/hdparm.c (revision 26173) @@ -293,15 +293,15 @@ unsigned long doorlock; unsigned long apmmode; #endif - USE_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;) - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint set_busstate, get_busstate;) - USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;) - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;) - USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;) - USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;) - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;) - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;) - USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;) + IF_FEATURE_HDPARM_GET_IDENTITY( smallint get_IDentity;) + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint set_busstate, get_busstate;) + IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( smallint perform_reset;) + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( smallint perform_tristate;) + IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(smallint unregister_hwif;) + IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( smallint scan_hwif;) + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long busstate;) + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( unsigned long tristate;) + IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(unsigned long hwif;) #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF unsigned long hwif_data; unsigned long hwif_ctrl; @@ -1960,12 +1960,12 @@ /*------- getopt short options --------*/ static const char hdparm_options[] ALIGN1 = "gfu::n::p:r::m::c::k::a::B:tT" - USE_FEATURE_HDPARM_GET_IDENTITY("iI") - USE_FEATURE_HDPARM_HDIO_GETSET_DMA("d::") + IF_FEATURE_HDPARM_GET_IDENTITY("iI") + IF_FEATURE_HDPARM_HDIO_GETSET_DMA("d::") #ifdef HDIO_DRIVE_CMD "S:D:P:X:K:A:L:W:CyYzZ" #endif - USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:") + IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF("U:") #ifdef HDIO_GET_QDMA #ifdef HDIO_SET_QDMA "Q:" @@ -1973,9 +1973,9 @@ "Q" #endif #endif - USE_FEATURE_HDPARM_HDIO_DRIVE_RESET("w") - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:") - USE_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:"); + IF_FEATURE_HDPARM_HDIO_DRIVE_RESET("w") + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF("x::b:") + IF_FEATURE_HDPARM_HDIO_SCAN_HWIF("R:"); /*-------------------------------------*/ /* our main() routine: */ @@ -1987,12 +1987,12 @@ while ((c = getopt(argc, argv, hdparm_options)) >= 0) { flagcount++; - USE_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); - USE_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i')); + IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); + IF_FEATURE_HDPARM_GET_IDENTITY(get_identity |= (c == 'i')); get_geom |= (c == 'g'); do_flush |= (c == 'f'); if (c == 'u') parse_opts(&get_unmask, &set_unmask, &unmask, 0, 1); - USE_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9)); + IF_FEATURE_HDPARM_HDIO_GETSET_DMA(if (c == 'd') parse_opts(&get_dma, &set_dma, &dma, 0, 9)); if (c == 'n') parse_opts(&get_nowerr, &set_nowerr, &nowerr, 0, 1); parse_xfermode((c == 'p'), &noisy_piomode, &set_piomode, &piomode); if (c == 'r') parse_opts(&get_readonly, &set_readonly, &readonly, 0, 1); @@ -2018,7 +2018,7 @@ reread_partn |= (c == 'z'); get_seagate = set_seagate |= (c == 'Z'); #endif - USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX)); + IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF(if (c == 'U') parse_opts(NULL, &unregister_hwif, &hwif, 0, INT_MAX)); #ifdef HDIO_GET_QDMA if (c == 'Q') { #ifdef HDIO_SET_QDMA @@ -2028,9 +2028,9 @@ #endif } #endif - USE_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r')); - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1)); - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2)); + IF_FEATURE_HDPARM_HDIO_DRIVE_RESET(perform_reset = (c == 'r')); + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'x') parse_opts(NULL, &perform_tristate, &tristate, 0, 1)); + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF(if (c == 'b') parse_opts(&get_busstate, &set_busstate, &busstate, 0, 2)); #if ENABLE_FEATURE_HDPARM_HDIO_SCAN_HWIF if (c == 'R') { parse_opts(NULL, &scan_hwif, &hwif_data, 0, INT_MAX); @@ -2045,7 +2045,7 @@ /* When no flags are given (flagcount = 0), -acdgkmnru is assumed. */ if (!flagcount) { get_mult = get_io32bit = get_unmask = get_keep = get_readonly = get_readahead = get_geom = 1; - USE_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1); + IF_FEATURE_HDPARM_HDIO_GETSET_DMA(get_dma = 1); } argv += optind; Index: miscutils/crond.c =================================================================== --- miscutils/crond.c (revision 26172) +++ miscutils/crond.c (revision 26173) @@ -162,11 +162,11 @@ INIT_G(); /* "-b after -f is ignored", and so on for every pair a-b */ - opt_complementary = "f-b:b-f:S-L:L-S" USE_FEATURE_CROND_D(":d-l") + opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") ":l+:d+"; /* -l and -d have numeric param */ - opt = getopt32(argv, "l:L:fbSc:" USE_FEATURE_CROND_D("d:"), + opt = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), &LogLevel, &LogFile, &CDir - USE_FEATURE_CROND_D(,&LogLevel)); + IF_FEATURE_CROND_D(,&LogLevel)); /* both -d N and -l N set the same variable: LogLevel */ if (!(opt & OPT_f)) { Index: miscutils/less.c =================================================================== --- miscutils/less.c (revision 26172) +++ miscutils/less.c (revision 26173) @@ -145,7 +145,7 @@ current_file = 1; \ eof_error = 1; \ terminated = 1; \ - USE_FEATURE_LESS_REGEXP(wanted_match = -1;) \ + IF_FEATURE_LESS_REGEXP(wanted_match = -1;) \ } while (0) /* flines[] are lines read from stdin, each in malloc'ed buffer. @@ -326,7 +326,7 @@ if (option_mask32 & FLAG_N) w -= 8; - USE_FEATURE_LESS_REGEXP(again0:) + IF_FEATURE_LESS_REGEXP(again0:) p = current_line = ((char*)xmalloc(w + 4)) + 4; max_fline += last_terminated; @@ -1509,7 +1509,7 @@ /* TODO: -x: do not interpret backspace, -xx: tab also */ /* -xxx: newline also */ /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ - getopt32(argv, "EMmN~I" USE_FEATURE_LESS_DASHCMD("S")); + getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S")); argc -= optind; argv += optind; num_files = argc; Index: miscutils/eject.c =================================================================== --- miscutils/eject.c (revision 26172) +++ miscutils/eject.c (revision 26173) @@ -89,7 +89,7 @@ const char *device; opt_complementary = "?1:t--T:T--t"; - flags = getopt32(argv, "tT" USE_FEATURE_EJECT_SCSI("s")); + flags = getopt32(argv, "tT" IF_FEATURE_EJECT_SCSI("s")); device = argv[optind] ? argv[optind] : "/dev/cdrom"; /* We used to do "umount " here, but it was buggy Index: include/libbb.h =================================================================== --- include/libbb.h (revision 26172) +++ include/libbb.h (revision 26173) @@ -260,7 +260,7 @@ FILEUTILS_SET_SECURITY_CONTEXT = 0x200 #endif }; -#define FILEUTILS_CP_OPTSTR "pdRfilsL" USE_SELINUX("c") +#define FILEUTILS_CP_OPTSTR "pdRfilsL" IF_SELINUX("c") extern int remove_file(const char *path, int flags) FAST_FUNC; /* NB: without FILEUTILS_RECUR in flags, it will basically "cat" * the source, not copy (unless "source" is a directory). @@ -916,15 +916,15 @@ /* Applets which are useful from another applets */ int bb_cat(char** argv); /* If shell needs them, they exist even if not enabled as applets */ -int echo_main(int argc, char** argv) USE_ECHO(MAIN_EXTERNALLY_VISIBLE); -int printf_main(int argc, char **argv) USE_PRINTF(MAIN_EXTERNALLY_VISIBLE); -int test_main(int argc, char **argv) USE_TEST(MAIN_EXTERNALLY_VISIBLE); -int kill_main(int argc, char **argv) USE_KILL(MAIN_EXTERNALLY_VISIBLE); +int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); +int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); +int test_main(int argc, char **argv) IF_TEST(MAIN_EXTERNALLY_VISIBLE); +int kill_main(int argc, char **argv) IF_KILL(MAIN_EXTERNALLY_VISIBLE); /* Similar, but used by chgrp, not shell */ -int chown_main(int argc, char **argv) USE_CHOWN(MAIN_EXTERNALLY_VISIBLE); +int chown_main(int argc, char **argv) IF_CHOWN(MAIN_EXTERNALLY_VISIBLE); /* Used by ftpd */ -int ls_main(int argc, char **argv) USE_LS(MAIN_EXTERNALLY_VISIBLE); -/* Don't need USE_xxx() guard for these */ +int ls_main(int argc, char **argv) IF_LS(MAIN_EXTERNALLY_VISIBLE); +/* Don't need IF_xxx() guard for these */ int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -1253,7 +1253,7 @@ /* Fields are set to 0/NULL if failed to determine (or not requested) */ uint16_t argv_len; char *argv0; - USE_SELINUX(char *context;) + IF_SELINUX(char *context;) /* Everything below must contain no ptrs to malloc'ed data: * it is memset(0) for each process in procps_scan() */ unsigned long vsz, rss; /* we round it to kbytes */ @@ -1309,7 +1309,7 @@ || ENABLE_PIDOF || ENABLE_SESTATUS ), - USE_SELINUX(PSSCAN_CONTEXT = 1 << 17,) + IF_SELINUX(PSSCAN_CONTEXT = 1 << 17,) PSSCAN_START_TIME = 1 << 18, PSSCAN_CPU = 1 << 19, /* These are all retrieved from proc/NN/stat in one go: */ Index: include/unarchive.h =================================================================== --- include/unarchive.h (revision 26172) +++ include/unarchive.h (revision 26173) @@ -125,24 +125,24 @@ uint32_t crc; } inflate_unzip_result; -USE_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; /* lzma unpacker takes .lzma stream from offset 0 */ -USE_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; /* the rest wants 2 first bytes already skipped by the caller */ -USE_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; -USE_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; -USE_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; -USE_DESKTOP(long long) int unpack_Z_stream(int fd_in, int fd_out) FAST_FUNC; +IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; +IF_DESKTOP(long long) int unpack_Z_stream(int fd_in, int fd_out) FAST_FUNC; /* wrapper which checks first two bytes to be "BZ" */ -USE_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; int bbunpack(char **argv, char* (*make_new_name)(char *filename), - USE_DESKTOP(long long) int (*unpacker)(unpack_info_t *info)) FAST_FUNC; + IF_DESKTOP(long long) int (*unpacker)(unpack_info_t *info)) FAST_FUNC; #if BB_MMU void open_transformer(int fd, - USE_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; + IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; #define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer) #else void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC; Index: include/usage.h =================================================================== --- include/usage.h (revision 26172) +++ include/usage.h (revision 26173) @@ -25,7 +25,7 @@ "\n -c DIR Config directory [/etc/acpi]" \ "\n -e FILE /proc event file [/proc/acpi/event]" \ "\n -l FILE Log file [/var/log/acpid]" \ - USE_FEATURE_ACPID_COMPAT( \ + IF_FEATURE_ACPID_COMPAT( \ "\n\nAccept and ignore compatibility options -g -m -s -S -v" \ ) @@ -34,9 +34,9 @@ "# acpid -d /dev/input/event*\n" #define addgroup_trivial_usage \ - "[-g GID] " USE_FEATURE_ADDUSER_TO_GROUP("[user_name] ") "group_name" + "[-g GID] " IF_FEATURE_ADDUSER_TO_GROUP("[user_name] ") "group_name" #define addgroup_full_usage "\n\n" \ - "Add a group " USE_FEATURE_ADDUSER_TO_GROUP("or add a user to a group") "\n" \ + "Add a group " IF_FEATURE_ADDUSER_TO_GROUP("or add a user to a group") "\n" \ "\nOptions:" \ "\n -g GID Group id" \ @@ -160,14 +160,14 @@ #define brctl_full_usage "\n\n" \ "Manage ethernet bridges.\n" \ "\nCommands:" \ - USE_FEATURE_BRCTL_SHOW( \ + IF_FEATURE_BRCTL_SHOW( \ "\n show Show a list of bridges" \ ) \ "\n addbr BRIDGE Create BRIDGE" \ "\n delbr BRIDGE Delete BRIDGE" \ "\n addif BRIDGE IFACE Add IFACE to BRIDGE" \ "\n delif BRIDGE IFACE Delete IFACE from BRIDGE" \ - USE_FEATURE_BRCTL_FANCY( \ + IF_FEATURE_BRCTL_FANCY( \ "\n setageing BRIDGE TIME Set ageing time" \ "\n setfd BRIDGE TIME Set bridge forward delay" \ "\n sethello BRIDGE TIME Set hello time" \ @@ -281,12 +281,12 @@ #define chcon_trivial_usage \ "[OPTIONS] CONTEXT FILE..." \ "\n chcon [OPTIONS] [-u USER] [-r ROLE] [-l RANGE] [-t TYPE] FILE..." \ - USE_FEATURE_CHCON_LONG_OPTIONS( \ + IF_FEATURE_CHCON_LONG_OPTIONS( \ "\n chcon [OPTIONS] --reference=RFILE FILE..." \ ) #define chcon_full_usage "\n\n" \ "Change the security context of each FILE to CONTEXT\n" \ - USE_FEATURE_CHCON_LONG_OPTIONS( \ + IF_FEATURE_CHCON_LONG_OPTIONS( \ "\n -v,--verbose Verbose" \ "\n -c,--changes Report changes made" \ "\n -h,--no-dereference Affect symlinks instead of their targets" \ @@ -298,7 +298,7 @@ "\n -l,--range=RANGE" \ "\n -R,--recursive Recurse subdirectories" \ ) \ - SKIP_FEATURE_CHCON_LONG_OPTIONS( \ + IF_NOT_FEATURE_CHCON_LONG_OPTIONS( \ "\n -v Verbose" \ "\n -c Report changes made" \ "\n -h Affect symlinks instead of their targets" \ @@ -311,13 +311,13 @@ ) #define chmod_trivial_usage \ - "[-R"USE_DESKTOP("cvf")"] MODE[,MODE]... FILE..." + "[-R"IF_DESKTOP("cvf")"] MODE[,MODE]... FILE..." #define chmod_full_usage "\n\n" \ "Each MODE is one or more of the letters ugoa, one of the\n" \ "symbols +-= and one or more of the letters rwxst\n" \ "\nOptions:" \ "\n -R Recurse directories" \ - USE_DESKTOP( \ + IF_DESKTOP( \ "\n -c List changed files" \ "\n -v List all files" \ "\n -f Hide errors" \ @@ -333,7 +333,7 @@ "-r--r--r-- 1 root root 0 Apr 12 18:25 /tmp/foo\n" #define chgrp_trivial_usage \ - "[-RhLHP"USE_DESKTOP("cvf")"]... GROUP FILE..." + "[-RhLHP"IF_DESKTOP("cvf")"]... GROUP FILE..." #define chgrp_full_usage "\n\n" \ "Change the group membership of each FILE to GROUP\n" \ "\nOptions:" \ @@ -342,7 +342,7 @@ "\n -L Traverse all symlinks to directories" \ "\n -H Traverse symlinks on command line only" \ "\n -P Do not traverse symlinks (default)" \ - USE_DESKTOP( \ + IF_DESKTOP( \ "\n -c List changed files" \ "\n -v Verbose" \ "\n -f Hide errors" \ @@ -355,7 +355,7 @@ "-r--r--r-- 1 andersen root 0 Apr 12 18:25 /tmp/foo\n" #define chown_trivial_usage \ - "[-RhLHP"USE_DESKTOP("cvf")"]... OWNER[<.|:>[GROUP]] FILE..." + "[-RhLHP"IF_DESKTOP("cvf")"]... OWNER[<.|:>[GROUP]] FILE..." #define chown_full_usage "\n\n" \ "Change the owner and/or group of each FILE to OWNER and/or GROUP\n" \ "\nOptions:" \ @@ -364,7 +364,7 @@ "\n -L Traverse all symlinks to directories" \ "\n -H Traverse symlinks on command line only" \ "\n -P Do not traverse symlinks (default)" \ - USE_DESKTOP( \ + IF_DESKTOP( \ "\n -c List changed files" \ "\n -v List all files" \ "\n -f Hide errors" \ @@ -468,7 +468,7 @@ "Clear screen" #define cmp_trivial_usage \ - "[-l] [-s] FILE1 [FILE2" USE_DESKTOP(" [SKIP1 [SKIP2]") "]]" + "[-l] [-s] FILE1 [FILE2" IF_DESKTOP(" [SKIP1 [SKIP2]") "]]" #define cmp_full_usage "\n\n" \ "Compares FILE1 vs stdin if FILE2 is not specified\n" \ "\nOptions:" \ @@ -518,7 +518,7 @@ "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY\n" \ "\nOptions:" \ "\n -a Same as -dpR" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -c Preserve security context" \ ) \ "\n -d,-P Preserve links" \ @@ -530,18 +530,18 @@ "\n -l,-s Create (sym)links" \ #define cpio_trivial_usage \ - "-[ti" USE_FEATURE_CPIO_O("o") USE_FEATURE_CPIO_P("p") "dmvu] [-F FILE]" \ - USE_FEATURE_CPIO_O( " [-H newc]" ) + "-[ti" IF_FEATURE_CPIO_O("o") IF_FEATURE_CPIO_P("p") "dmvu] [-F FILE]" \ + IF_FEATURE_CPIO_O( " [-H newc]" ) #define cpio_full_usage "\n\n" \ "Extract or list files from a cpio archive" \ - USE_FEATURE_CPIO_O( ", or create a cpio archive" ) \ + IF_FEATURE_CPIO_O( ", or create a cpio archive" ) \ "\nMain operation mode:" \ "\n -t List" \ "\n -i Extract" \ - USE_FEATURE_CPIO_O( \ + IF_FEATURE_CPIO_O( \ "\n -o Create" \ ) \ - USE_FEATURE_CPIO_P( \ + IF_FEATURE_CPIO_P( \ "\n -p Passthrough" \ ) \ "\nOptions:" \ @@ -550,18 +550,18 @@ "\n -v Verbose" \ "\n -u Overwrite" \ "\n -F Input file" \ - USE_FEATURE_CPIO_O( \ + IF_FEATURE_CPIO_O( \ "\n -H Define format" \ ) \ #define crond_trivial_usage \ - "-fbS -l N " USE_FEATURE_CROND_D("-d N ") "-L LOGFILE -c DIR" + "-fbS -l N " IF_FEATURE_CROND_D("-d N ") "-L LOGFILE -c DIR" #define crond_full_usage "\n\n" \ " -f Foreground" \ "\n -b Background (default)" \ "\n -S Log to syslog (default)" \ "\n -l Set log level. 0 is the most verbose, default 8" \ - USE_FEATURE_CROND_D( \ + IF_FEATURE_CROND_D( \ "\n -d Set log level, log to stderr" \ ) \ "\n -L Log to file" \ @@ -583,13 +583,13 @@ #define cryptpw_full_usage "\n\n" \ "Crypt the PASSWORD using crypt(3)\n" \ "\nOptions:" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ "\n -P,--password-fd=NUM Read password from fd NUM" \ /* "\n -s,--stdin Use stdin; like -P0" */ \ "\n -m,--method=TYPE Encryption method TYPE" \ "\n -S,--salt=SALT" \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ "\n -P NUM Read password from fd NUM" \ /* "\n -s Use stdin; like -P0" */ \ "\n -m TYPE Encryption method TYPE" \ @@ -604,13 +604,13 @@ #define mkpasswd_full_usage "\n\n" \ "Crypt the PASSWORD using crypt(3)\n" \ "\nOptions:" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ "\n -P,--password-fd=NUM Read password from fd NUM" \ /* "\n -s,--stdin Use stdin; like -P0" */ \ "\n -m,--method=TYPE Encryption method TYPE" \ "\n -S,--salt=SALT" \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ "\n -P NUM Read password from fd NUM" \ /* "\n -s Use stdin; like -P0" */ \ "\n -m TYPE Encryption method TYPE" \ @@ -645,7 +645,7 @@ "\nOptions:" \ "\n -u Work in UTC (don't convert to local time)" \ "\n -R Output RFC-822 compliant date string" \ - USE_FEATURE_DATE_ISOFMT( \ + IF_FEATURE_DATE_ISOFMT( \ "\n -I[SPEC] Output ISO-8601 compliant date string" \ "\n SPEC='date' (default) for date only," \ "\n 'hours', 'minutes', or 'seconds' for date and" \ @@ -654,7 +654,7 @@ "\n -d TIME Display TIME, not 'now'" \ "\n -r FILE Display last modification time of FILE" \ "\n [-s] TIME Set time to TIME" \ - USE_FEATURE_DATE_ISOFMT( \ + IF_FEATURE_DATE_ISOFMT( \ "\n -D FMT Use FMT for str->date conversion" \ ) \ "\n" \ @@ -691,24 +691,24 @@ "64\n" #define dd_trivial_usage \ - "[if=FILE] [of=FILE] " USE_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" \ - " [seek=N]" USE_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") + "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" \ + " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") #define dd_full_usage "\n\n" \ "Copy a file with converting and formatting\n" \ "\nOptions:" \ "\n if=FILE Read from FILE instead of stdin" \ "\n of=FILE Write to FILE instead of stdout" \ "\n bs=N Read and write N bytes at a time" \ - USE_FEATURE_DD_IBS_OBS( \ + IF_FEATURE_DD_IBS_OBS( \ "\n ibs=N Read N bytes at a time" \ ) \ - USE_FEATURE_DD_IBS_OBS( \ + IF_FEATURE_DD_IBS_OBS( \ "\n obs=N Write N bytes at a time" \ ) \ "\n count=N Copy only N input blocks" \ "\n skip=N Skip N input blocks" \ "\n seek=N Skip N output blocks" \ - USE_FEATURE_DD_IBS_OBS( \ + IF_FEATURE_DD_IBS_OBS( \ "\n conv=notrunc Don't truncate output file" \ "\n conv=noerror Continue after read errors" \ "\n conv=sync Pad blocks with zeros" \ @@ -729,10 +729,10 @@ "Deallocate unused virtual terminal /dev/ttyN" #define delgroup_trivial_usage \ - USE_FEATURE_DEL_USER_FROM_GROUP("[USER] ")"GROUP" + IF_FEATURE_DEL_USER_FROM_GROUP("[USER] ")"GROUP" #define delgroup_full_usage "\n\n" \ "Delete group GROUP from the system" \ - USE_FEATURE_DEL_USER_FROM_GROUP(" or user USER from group GROUP") + IF_FEATURE_DEL_USER_FROM_GROUP(" or user USER from group GROUP") #define deluser_trivial_usage \ "USER" @@ -752,14 +752,14 @@ "\n VALUE Data to be written" \ #define devfsd_trivial_usage \ - "mntpnt [-v]" USE_DEVFSD_FG_NP("[-fg][-np]") + "mntpnt [-v]" IF_DEVFSD_FG_NP("[-fg][-np]") #define devfsd_full_usage "\n\n" \ "Manage devfs permissions and old device name symlinks\n" \ "\nOptions:" \ "\n mntpnt The mount point where devfs is mounted" \ "\n -v Print the protocol version numbers for devfsd" \ "\n and the kernel-side protocol version and exit" \ - USE_DEVFSD_FG_NP( \ + IF_DEVFSD_FG_NP( \ "\n -fg Run in foreground" \ "\n -np Exit after parsing the configuration file" \ "\n and processing synthetic REGISTER events," \ @@ -768,19 +768,19 @@ #define df_trivial_usage \ "[-Pk" \ - USE_FEATURE_HUMAN_READABLE("mh") \ - USE_FEATURE_DF_FANCY("ai] [-B SIZE") \ + IF_FEATURE_HUMAN_READABLE("mh") \ + IF_FEATURE_DF_FANCY("ai] [-B SIZE") \ "] [FILESYSTEM...]" #define df_full_usage "\n\n" \ "Print filesystem usage statistics\n" \ "\nOptions:" \ "\n -P POSIX output format" \ "\n -k 1024-byte blocks (default)" \ - USE_FEATURE_HUMAN_READABLE( \ + IF_FEATURE_HUMAN_READABLE( \ "\n -m 1M-byte blocks" \ "\n -h Human readable (e.g. 1K 243M 2G)" \ ) \ - USE_FEATURE_DF_FANCY( \ + IF_FEATURE_DF_FANCY( \ "\n -a Show all filesystems" \ "\n -i Inodes" \ "\n -B SIZE Blocksize" \ @@ -894,12 +894,12 @@ "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n" #define du_trivial_usage \ - "[-aHLdclsx" USE_FEATURE_HUMAN_READABLE("hm") "k] [FILE]..." + "[-aHLdclsx" IF_FEATURE_HUMAN_READABLE("hm") "k] [FILE]..." #define du_full_usage "\n\n" \ "Summarize disk space used for each FILE and/or directory.\n" \ "Disk space is printed in units of " \ - USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K("1024") \ - SKIP_FEATURE_DU_DEFAULT_BLOCKSIZE_1K("512") \ + IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K("1024") \ + IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K("512") \ " bytes.\n" \ "\nOptions:" \ "\n -a Show file sizes too" \ @@ -910,12 +910,12 @@ "\n -l Count sizes many times if hard linked" \ "\n -s Display only a total for each argument" \ "\n -x Skip directories on different filesystems" \ - USE_FEATURE_HUMAN_READABLE( \ + IF_FEATURE_HUMAN_READABLE( \ "\n -h Sizes in human readable format (e.g., 1K 243M 2G )" \ "\n -m Sizes in megabytes" \ ) \ "\n -k Sizes in kilobytes" \ - USE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(" (default)") \ + IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(" (default)") \ #define du_example_usage \ "$ du\n" \ @@ -942,12 +942,12 @@ #define dumpleases_full_usage "\n\n" \ "Display DHCP leases granted by udhcpd\n" \ "\nOptions:" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ "\n -f,--file=FILE Leases file to load" \ "\n -r,--remaining Interpret lease times as time remaining" \ "\n -a,--absolute Interpret lease times as expire time" \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ "\n -f FILE Leases file to load" \ "\n -r Interpret lease times as time remaining" \ "\n -a Interpret lease times as expire time" \ @@ -974,10 +974,10 @@ "\n -L file Set badblocks list" \ #define echo_trivial_usage \ - USE_FEATURE_FANCY_ECHO("[-neE] ") "[ARG...]" + IF_FEATURE_FANCY_ECHO("[-neE] ") "[ARG...]" #define echo_full_usage "\n\n" \ "Print the specified ARGs to stdout" \ - USE_FEATURE_FANCY_ECHO( "\n" \ + IF_FEATURE_FANCY_ECHO( "\n" \ "\nOptions:" \ "\n -n Suppress trailing newline" \ "\n -e Interpret backslash-escaped characters (i.e., \\t=tab)" \ @@ -986,7 +986,7 @@ #define echo_example_usage \ "$ echo \"Erik is cool\"\n" \ "Erik is cool\n" \ - USE_FEATURE_FANCY_ECHO("$ echo -e \"Erik\\nis\\ncool\"\n" \ + IF_FEATURE_FANCY_ECHO("$ echo -e \"Erik\\nis\\ncool\"\n" \ "Erik\n" \ "is\n" \ "cool\n" \ @@ -998,7 +998,7 @@ #define eject_full_usage "\n\n" \ "Eject specified DEVICE (or default /dev/cdrom)\n" \ "\nOptions:" \ - USE_FEATURE_EJECT_SCSI( \ + IF_FEATURE_EJECT_SCSI( \ "\n -s SCSI device" \ ) \ "\n -t Close tray" \ @@ -1032,11 +1032,11 @@ #define expand_full_usage "\n\n" \ "Convert tabs to spaces, writing to standard output.\n" \ "\nOptions:" \ - USE_FEATURE_EXPAND_LONG_OPTIONS( \ + IF_FEATURE_EXPAND_LONG_OPTIONS( \ "\n -i,--initial Do not convert tabs after non blanks" \ "\n -t,--tabs=N Tabstops every N chars" \ ) \ - SKIP_FEATURE_EXPAND_LONG_OPTIONS( \ + IF_NOT_FEATURE_EXPAND_LONG_OPTIONS( \ "\n -i Do not convert tabs after non blanks" \ "\n -t Tabstops every N chars" \ ) @@ -1127,18 +1127,18 @@ /* Looks like someone forgot to add this to config system */ #ifndef ENABLE_FEATURE_FDISK_BLKSIZE # define ENABLE_FEATURE_FDISK_BLKSIZE 0 -# define USE_FEATURE_FDISK_BLKSIZE(a) +# define IF_FEATURE_FDISK_BLKSIZE(a) #endif #define fdisk_trivial_usage \ - "[-ul" USE_FEATURE_FDISK_BLKSIZE("s") "] " \ + "[-ul" IF_FEATURE_FDISK_BLKSIZE("s") "] " \ "[-C CYLINDERS] [-H HEADS] [-S SECTORS] [-b SSZ] DISK" #define fdisk_full_usage "\n\n" \ "Change partition table\n" \ "\nOptions:" \ "\n -u Start and End are in sectors (instead of cylinders)" \ "\n -l Show partition table for each DISK, then exit" \ - USE_FEATURE_FDISK_BLKSIZE( \ + IF_FEATURE_FDISK_BLKSIZE( \ "\n -s Show partition sizes in kb for each DISK, then exit" \ ) \ "\n -b 2048 (for certain MO disks) use 2048-byte sectors" \ @@ -1165,56 +1165,56 @@ "default EXPRESSION is '-print'\n" \ "\nEXPRESSION may consist of:" \ "\n -follow Dereference symlinks" \ - USE_FEATURE_FIND_XDEV( \ + IF_FEATURE_FIND_XDEV( \ "\n -xdev Don't descend directories on other filesystems") \ - USE_FEATURE_FIND_MAXDEPTH( \ + IF_FEATURE_FIND_MAXDEPTH( \ "\n -maxdepth N Descend at most N levels. -maxdepth 0 applies" \ "\n tests/actions to command line arguments only") \ "\n -mindepth N Do not act on first N levels" \ "\n -name PATTERN File name (w/o directory name) matches PATTERN" \ "\n -iname PATTERN Case insensitive -name" \ - USE_FEATURE_FIND_PATH( \ + IF_FEATURE_FIND_PATH( \ "\n -path PATTERN Path matches PATTERN") \ - USE_FEATURE_FIND_REGEX( \ + IF_FEATURE_FIND_REGEX( \ "\n -regex PATTERN Path matches regex PATTERN") \ - USE_FEATURE_FIND_TYPE( \ + IF_FEATURE_FIND_TYPE( \ "\n -type X File type is X (X is one of: f,d,l,b,c,...)") \ - USE_FEATURE_FIND_PERM( \ + IF_FEATURE_FIND_PERM( \ "\n -perm NNN Permissions match any of (+NNN), all of (-NNN)," \ "\n or exactly (NNN)") \ - USE_FEATURE_FIND_MTIME( \ + IF_FEATURE_FIND_MTIME( \ "\n -mtime DAYS Modified time is greater than (+N), less than (-N)," \ "\n or exactly (N) days") \ - USE_FEATURE_FIND_MMIN( \ + IF_FEATURE_FIND_MMIN( \ "\n -mmin MINS Modified time is greater than (+N), less than (-N)," \ "\n or exactly (N) minutes") \ - USE_FEATURE_FIND_NEWER( \ + IF_FEATURE_FIND_NEWER( \ "\n -newer FILE Modified time is more recent than FILE's") \ - USE_FEATURE_FIND_INUM( \ + IF_FEATURE_FIND_INUM( \ "\n -inum N File has inode number N") \ - USE_FEATURE_FIND_USER( \ + IF_FEATURE_FIND_USER( \ "\n -user NAME File is owned by user NAME (numeric user ID allowed)") \ - USE_FEATURE_FIND_GROUP( \ + IF_FEATURE_FIND_GROUP( \ "\n -group NAME File belongs to group NAME (numeric group ID allowed)") \ - USE_FEATURE_FIND_DEPTH( \ + IF_FEATURE_FIND_DEPTH( \ "\n -depth Process directory name after traversing it") \ - USE_FEATURE_FIND_SIZE( \ + IF_FEATURE_FIND_SIZE( \ "\n -size N[bck] File size is N (c:bytes,k:kbytes,b:512 bytes(def.))." \ "\n +/-N: file size is bigger/smaller than N") \ "\n -print Print (default and assumed)" \ - USE_FEATURE_FIND_PRINT0( \ + IF_FEATURE_FIND_PRINT0( \ "\n -print0 Delimit output with null characters rather than" \ "\n newlines") \ - USE_FEATURE_FIND_CONTEXT ( \ + IF_FEATURE_FIND_CONTEXT ( \ "\n -context File has specified security context") \ - USE_FEATURE_FIND_EXEC( \ + IF_FEATURE_FIND_EXEC( \ "\n -exec CMD ARG ; Execute CMD with all instances of {} replaced by the" \ "\n matching files") \ - USE_FEATURE_FIND_PRUNE( \ + IF_FEATURE_FIND_PRUNE( \ "\n -prune Stop traversing current subtree") \ - USE_FEATURE_FIND_DELETE( \ + IF_FEATURE_FIND_DELETE( \ "\n -delete Delete files, turns on -depth option") \ - USE_FEATURE_FIND_PAREN( \ + IF_FEATURE_FIND_PAREN( \ "\n (EXPR) Group an expression") \ #define find_example_usage \ @@ -1306,14 +1306,14 @@ #define ftpget_full_usage "\n\n" \ "Retrieve a remote file via FTP\n" \ "\nOptions:" \ - USE_FEATURE_FTPGETPUT_LONG_OPTIONS( \ + IF_FEATURE_FTPGETPUT_LONG_OPTIONS( \ "\n -c,--continue Continue previous transfer" \ "\n -v,--verbose Verbose" \ "\n -u,--username Username" \ "\n -p,--password Password" \ "\n -P,--port Port number" \ ) \ - SKIP_FEATURE_FTPGETPUT_LONG_OPTIONS( \ + IF_NOT_FEATURE_FTPGETPUT_LONG_OPTIONS( \ "\n -c Continue previous transfer" \ "\n -v Verbose" \ "\n -u Username" \ @@ -1326,13 +1326,13 @@ #define ftpput_full_usage "\n\n" \ "Store a local file on a remote machine via FTP\n" \ "\nOptions:" \ - USE_FEATURE_FTPGETPUT_LONG_OPTIONS( \ + IF_FEATURE_FTPGETPUT_LONG_OPTIONS( \ "\n -v,--verbose Verbose" \ "\n -u,--username Username" \ "\n -p,--password Password" \ "\n -P,--port Port number" \ ) \ - SKIP_FEATURE_FTPGETPUT_LONG_OPTIONS( \ + IF_NOT_FEATURE_FTPGETPUT_LONG_OPTIONS( \ "\n -v Verbose" \ "\n -u Username" \ "\n -p Password" \ @@ -1358,7 +1358,7 @@ "[OPTIONS]..." #define getopt_full_usage "\n\n" \ "Parse command options\n" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ "\n -a,--alternative Allow long options starting with single -" \ "\n -l,--longoptions=longopts Long options to be recognized" \ "\n -n,--name=progname The name under which errors are reported" \ @@ -1369,7 +1369,7 @@ "\n -T,--test Test for getopt(1) version" \ "\n -u,--unquoted Don't quote the output" \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ "\n -a Allow long options starting with single -" \ "\n -l longopts Long options to be recognized" \ "\n -n progname The name under which errors are reported" \ @@ -1425,11 +1425,11 @@ #define grep_trivial_usage \ "[-HhrilLnqvso" \ - USE_DESKTOP("w") \ + IF_DESKTOP("w") \ "eF" \ - USE_FEATURE_GREP_EGREP_ALIAS("E") \ - USE_FEATURE_GREP_CONTEXT("ABC") \ - USE_EXTRA_COMPAT("z") \ + IF_FEATURE_GREP_EGREP_ALIAS("E") \ + IF_FEATURE_GREP_CONTEXT("ABC") \ + IF_EXTRA_COMPAT("z") \ "] PATTERN [FILEs...]" #define grep_full_usage "\n\n" \ "Search for PATTERN in each FILE or standard input\n" \ @@ -1447,18 +1447,18 @@ "\n -c Only print count of matching lines" \ "\n -o Show only the part of a line that matches PATTERN" \ "\n -m MAX Match up to MAX times per file" \ - USE_DESKTOP( \ + IF_DESKTOP( \ "\n -w Match whole words only") \ "\n -F PATTERN is a set of newline-separated strings" \ - USE_FEATURE_GREP_EGREP_ALIAS( \ + IF_FEATURE_GREP_EGREP_ALIAS( \ "\n -E PATTERN is an extended regular expression") \ "\n -e PTRN Pattern to match" \ "\n -f FILE Read pattern from file" \ - USE_FEATURE_GREP_CONTEXT( \ + IF_FEATURE_GREP_CONTEXT( \ "\n -A Print NUM lines of trailing context" \ "\n -B Print NUM lines of leading context" \ "\n -C Print NUM lines of output context") \ - USE_EXTRA_COMPAT( \ + IF_EXTRA_COMPAT( \ "\n -z Input is NUL terminated") \ #define grep_example_usage \ @@ -1506,14 +1506,14 @@ "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n" #define halt_trivial_usage \ - "[-d delay] [-n] [-f]" USE_FEATURE_WTMP(" [-w]") + "[-d delay] [-n] [-f]" IF_FEATURE_WTMP(" [-w]") #define halt_full_usage "\n\n" \ "Halt the system\n" \ "\nOptions:" \ "\n -d Delay interval for halting" \ "\n -n No call to sync()" \ "\n -f Force halt (don't go through init)" \ - USE_FEATURE_WTMP( \ + IF_FEATURE_WTMP( \ "\n -w Only write a wtmp record" \ ) @@ -1527,15 +1527,15 @@ "\n -B Set Advanced Power Management setting (1-255)" \ "\n -c Get/set IDE 32-bit IO setting" \ "\n -C Check IDE power mode status" \ - USE_FEATURE_HDPARM_HDIO_GETSET_DMA( \ + IF_FEATURE_HDPARM_HDIO_GETSET_DMA( \ "\n -d Get/set using_dma flag") \ "\n -D Enable/disable drive defect-mgmt" \ "\n -f Flush buffer cache for device on exit" \ "\n -g Display drive geometry" \ "\n -h Display terse usage information" \ - USE_FEATURE_HDPARM_GET_IDENTITY( \ + IF_FEATURE_HDPARM_GET_IDENTITY( \ "\n -i Display drive identification") \ - USE_FEATURE_HDPARM_GET_IDENTITY( \ + IF_FEATURE_HDPARM_GET_IDENTITY( \ "\n -I Detailed/current information directly from drive") \ "\n -k Get/set keep_settings_over_reset flag (0/1)" \ "\n -K Set drive keep_features_over_reset flag (0/1)" \ @@ -1547,20 +1547,20 @@ /* "\n -q Change next setting quietly" - not supported ib bbox */ \ "\n -Q Get/set DMA tagged-queuing depth (if supported)" \ "\n -r Get/set readonly flag (DANGEROUS to set)" \ - USE_FEATURE_HDPARM_HDIO_SCAN_HWIF( \ + IF_FEATURE_HDPARM_HDIO_SCAN_HWIF( \ "\n -R Register an IDE interface (DANGEROUS)") \ "\n -S Set standby (spindown) timeout" \ "\n -t Perform device read timings" \ "\n -T Perform cache read timings" \ "\n -u Get/set unmaskirq flag (0/1)" \ - USE_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF( \ + IF_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF( \ "\n -U Un-register an IDE interface (DANGEROUS)") \ "\n -v Defaults; same as -mcudkrag for IDE drives" \ "\n -V Display program version and exit immediately" \ - USE_FEATURE_HDPARM_HDIO_DRIVE_RESET( \ + IF_FEATURE_HDPARM_HDIO_DRIVE_RESET( \ "\n -w Perform device reset (DANGEROUS)") \ "\n -W Set drive write-caching flag (0/1) (DANGEROUS)" \ - USE_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( \ + IF_FEATURE_HDPARM_HDIO_TRISTATE_HWIF( \ "\n -x Tristate device for hotswap (0/1) (DANGEROUS)") \ "\n -X Set IDE xfer mode (DANGEROUS)" \ "\n -y Put IDE drive in standby mode" \ @@ -1576,7 +1576,7 @@ "file name. With no FILE, or when FILE is -, read standard input.\n" \ "\nOptions:" \ "\n -n NUM Print first NUM lines instead of first 10" \ - USE_FEATURE_FANCY_HEAD( \ + IF_FEATURE_FANCY_HEAD( \ "\n -c NUM Output the first NUM bytes" \ "\n -q Never output headers giving file names" \ "\n -v Always output headers giving file names") \ @@ -1587,7 +1587,7 @@ "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n" #define hexdump_trivial_usage \ - "[-bcCdefnosvx" USE_FEATURE_HEXDUMP_REVERSE("R") "] FILE..." + "[-bcCdefnosvx" IF_FEATURE_HEXDUMP_REVERSE("R") "] FILE..." #define hexdump_full_usage "\n\n" \ "Display file(s) or standard input in a user specified format\n" \ "\nOptions:" \ @@ -1602,7 +1602,7 @@ "\n -s OFFSET Skip OFFSET bytes" \ "\n -v Display all input data" \ "\n -x Two-byte hexadecimal display" \ - USE_FEATURE_HEXDUMP_REVERSE( \ + IF_FEATURE_HEXDUMP_REVERSE( \ "\n -R Reverse of 'hexdump -Cv'") \ #define hd_trivial_usage \ @@ -1634,9 +1634,9 @@ "[-c conffile]" \ " [-p [ip:]port]" \ " [-i] [-f] [-v[v]]" \ - USE_FEATURE_HTTPD_SETUID(" [-u user[:grp]]") \ - USE_FEATURE_HTTPD_BASIC_AUTH(" [-r realm]") \ - USE_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \ + IF_FEATURE_HTTPD_SETUID(" [-u user[:grp]]") \ + IF_FEATURE_HTTPD_BASIC_AUTH(" [-r realm]") \ + IF_FEATURE_HTTPD_AUTH_MD5(" [-m pass]") \ " [-h home]" \ " [-d/-e string]" #define httpd_full_usage "\n\n" \ @@ -1647,23 +1647,23 @@ "\n -i Inetd mode" \ "\n -f Do not daemonize" \ "\n -v[v] Verbose" \ - USE_FEATURE_HTTPD_SETUID( \ + IF_FEATURE_HTTPD_SETUID( \ "\n -u USER[:GRP] Set uid/gid after binding to port") \ - USE_FEATURE_HTTPD_BASIC_AUTH( \ + IF_FEATURE_HTTPD_BASIC_AUTH( \ "\n -r REALM Authentication Realm for Basic Authentication") \ - USE_FEATURE_HTTPD_AUTH_MD5( \ + IF_FEATURE_HTTPD_AUTH_MD5( \ "\n -m PASS Crypt PASS with md5 algorithm") \ "\n -h HOME Home directory (default .)" \ "\n -e STRING HTML encode STRING" \ "\n -d STRING URL decode STRING" \ #define hwclock_trivial_usage \ - USE_FEATURE_HWCLOCK_LONG_OPTIONS( \ + IF_FEATURE_HWCLOCK_LONG_OPTIONS( \ "[-r|--show] [-s|--hctosys] [-w|--systohc]" \ " [-l|--localtime] [-u|--utc]" \ " [-f FILE]" \ ) \ - SKIP_FEATURE_HWCLOCK_LONG_OPTIONS( \ + IF_NOT_FEATURE_HWCLOCK_LONG_OPTIONS( \ "[-r] [-s] [-w] [-l] [-u] [-f FILE]" \ ) #define hwclock_full_usage "\n\n" \ @@ -1681,7 +1681,7 @@ #define id_full_usage "\n\n" \ "Print information about USER or the current user\n" \ "\nOptions:" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Print the security context" \ ) \ "\n -u Print user ID" \ @@ -1695,23 +1695,23 @@ "uid=1000(andersen) gid=1000(andersen)\n" #define ifconfig_trivial_usage \ - USE_FEATURE_IFCONFIG_STATUS("[-a]") " interface [address]" + IF_FEATURE_IFCONFIG_STATUS("[-a]") " interface [address]" #define ifconfig_full_usage "\n\n" \ "Configure a network interface\n" \ "\nOptions:" \ "\n" \ - USE_FEATURE_IPV6( \ + IF_FEATURE_IPV6( \ " [add ADDRESS[/PREFIXLEN]]\n") \ - USE_FEATURE_IPV6( \ + IF_FEATURE_IPV6( \ " [del ADDRESS[/PREFIXLEN]]\n") \ " [[-]broadcast [ADDRESS]] [[-]pointopoint [ADDRESS]]\n" \ " [netmask ADDRESS] [dstaddr ADDRESS]\n" \ - USE_FEATURE_IFCONFIG_SLIP( \ + IF_FEATURE_IFCONFIG_SLIP( \ " [outfill NN] [keepalive NN]\n") \ - " " USE_FEATURE_IFCONFIG_HW("[hw ether" USE_FEATURE_HWIB("|infiniband")" ADDRESS] ") "[metric NN] [mtu NN]\n" \ + " " IF_FEATURE_IFCONFIG_HW("[hw ether" IF_FEATURE_HWIB("|infiniband")" ADDRESS] ") "[metric NN] [mtu NN]\n" \ " [[-]trailers] [[-]arp] [[-]allmulti]\n" \ " [multicast] [[-]promisc] [txqueuelen NN] [[-]dynamic]\n" \ - USE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ( \ + IF_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ( \ " [mem_start NN] [io_addr NN] [irq NN]\n") \ " [up|down] ..." @@ -1743,13 +1743,13 @@ " # ifenslave -c bond0 eth0\n" \ #define ifup_trivial_usage \ - "[-ain"USE_FEATURE_IFUPDOWN_MAPPING("m")"vf] ifaces..." + "[-ain"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] ifaces..." #define ifup_full_usage "\n\n" \ "Options:" \ "\n -a De/configure all interfaces automatically" \ "\n -i FILE Use FILE for interface definitions" \ "\n -n Print out what would happen, but don't do it" \ - USE_FEATURE_IFUPDOWN_MAPPING( \ + IF_FEATURE_IFUPDOWN_MAPPING( \ "\n (note: doesn't disable mappings)" \ "\n -m Don't run any mappings" \ ) \ @@ -1757,13 +1757,13 @@ "\n -f Force de/configuration" \ #define ifdown_trivial_usage \ - "[-ain"USE_FEATURE_IFUPDOWN_MAPPING("m")"vf] ifaces..." + "[-ain"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] ifaces..." #define ifdown_full_usage "\n\n" \ "Options:" \ "\n -a De/configure all interfaces automatically" \ "\n -i FILE Use FILE for interface definitions" \ "\n -n Print out what would happen, but don't do it" \ - USE_FEATURE_IFUPDOWN_MAPPING( \ + IF_FEATURE_IFUPDOWN_MAPPING( \ "\n (note: doesn't disable mappings)" \ "\n -m Don't run any mappings" \ ) \ @@ -1943,19 +1943,19 @@ /* 2.6 style insmod has no options and required filename * (not module name - .ko can't be omitted) */ #define insmod_trivial_usage \ - USE_FEATURE_2_4_MODULES("[OPTION]... MODULE ") \ - SKIP_FEATURE_2_4_MODULES("FILE ") \ + IF_FEATURE_2_4_MODULES("[OPTION]... MODULE ") \ + IF_NOT_FEATURE_2_4_MODULES("FILE ") \ "[symbol=value]..." #define insmod_full_usage "\n\n" \ "Load the specified kernel modules into the kernel" \ - USE_FEATURE_2_4_MODULES( "\n" \ + IF_FEATURE_2_4_MODULES( "\n" \ "\nOptions:" \ "\n -f Force module to load into the wrong kernel version" \ "\n -k Make module autoclean-able" \ "\n -v Verbose" \ "\n -q Quiet" \ "\n -L Lock to prevent simultaneous loads of a module" \ - USE_FEATURE_INSMOD_LOAD_MAP( \ + IF_FEATURE_INSMOD_LOAD_MAP( \ "\n -m Output load map to stdout" \ ) \ "\n -o NAME Set internal module name to NAME" \ @@ -1976,7 +1976,7 @@ "\n -o USER Set ownership" \ "\n -g GRP Set group ownership" \ "\n -m MODE Set permissions" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Set security context" \ ) @@ -1991,20 +1991,20 @@ /* would need to make the " | " optional depending on more than one selected: */ #define ip_trivial_usage \ "[OPTIONS] {" \ - USE_FEATURE_IP_ADDRESS("address | ") \ - USE_FEATURE_IP_ROUTE("route | ") \ - USE_FEATURE_IP_LINK("link | ") \ - USE_FEATURE_IP_TUNNEL("tunnel | ") \ - USE_FEATURE_IP_RULE("rule") \ + IF_FEATURE_IP_ADDRESS("address | ") \ + IF_FEATURE_IP_ROUTE("route | ") \ + IF_FEATURE_IP_LINK("link | ") \ + IF_FEATURE_IP_TUNNEL("tunnel | ") \ + IF_FEATURE_IP_RULE("rule") \ "} {COMMAND}" #define ip_full_usage "\n\n" \ "ip [OPTIONS] OBJECT {COMMAND}\n" \ "where OBJECT := {" \ - USE_FEATURE_IP_ADDRESS("address | ") \ - USE_FEATURE_IP_ROUTE("route | ") \ - USE_FEATURE_IP_LINK("link | ") \ - USE_FEATURE_IP_TUNNEL("tunnel | ") \ - USE_FEATURE_IP_RULE("rule") \ + IF_FEATURE_IP_ADDRESS("address | ") \ + IF_FEATURE_IP_ROUTE("route | ") \ + IF_FEATURE_IP_LINK("link | ") \ + IF_FEATURE_IP_TUNNEL("tunnel | ") \ + IF_FEATURE_IP_RULE("rule") \ "}\n" \ "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }" \ @@ -2025,21 +2025,21 @@ #define ipcalc_full_usage "\n\n" \ "Calculate IP network settings from a IP address\n" \ "\nOptions:" \ - USE_FEATURE_IPCALC_LONG_OPTIONS( \ + IF_FEATURE_IPCALC_LONG_OPTIONS( \ "\n -b,--broadcast Display calculated broadcast address" \ "\n -n,--network Display calculated network address" \ "\n -m,--netmask Display default netmask for IP" \ - USE_FEATURE_IPCALC_FANCY( \ + IF_FEATURE_IPCALC_FANCY( \ "\n -p,--prefix Display the prefix for IP/NETMASK" \ "\n -h,--hostname Display first resolved host name" \ "\n -s,--silent Don't ever display error messages" \ ) \ ) \ - SKIP_FEATURE_IPCALC_LONG_OPTIONS( \ + IF_NOT_FEATURE_IPCALC_LONG_OPTIONS( \ "\n -b Display calculated broadcast address" \ "\n -n Display calculated network address" \ "\n -m Display default netmask for IP" \ - USE_FEATURE_IPCALC_FANCY( \ + IF_FEATURE_IPCALC_FANCY( \ "\n -p Display the prefix for IP/NETMASK" \ "\n -h Display first resolved host name" \ "\n -s Don't ever display error messages" \ @@ -2332,14 +2332,14 @@ "\n -V Verbose" \ #define ls_trivial_usage \ - "[-1Aa" USE_FEATURE_LS_TIMESTAMPS("c") "Cd" \ - USE_FEATURE_LS_TIMESTAMPS("e") USE_FEATURE_LS_FILETYPES("F") "iln" \ - USE_FEATURE_LS_FILETYPES("p") USE_FEATURE_LS_FOLLOWLINKS("L") \ - USE_FEATURE_LS_RECURSIVE("R") USE_FEATURE_LS_SORTFILES("rS") "s" \ - USE_FEATURE_AUTOWIDTH("T") USE_FEATURE_LS_TIMESTAMPS("tu") \ - USE_FEATURE_LS_SORTFILES("v") USE_FEATURE_AUTOWIDTH("w") "x" \ - USE_FEATURE_LS_SORTFILES("X") USE_FEATURE_HUMAN_READABLE("h") "k" \ - USE_SELINUX("K") "] [filenames...]" + "[-1Aa" IF_FEATURE_LS_TIMESTAMPS("c") "Cd" \ + IF_FEATURE_LS_TIMESTAMPS("e") IF_FEATURE_LS_FILETYPES("F") "iln" \ + IF_FEATURE_LS_FILETYPES("p") IF_FEATURE_LS_FOLLOWLINKS("L") \ + IF_FEATURE_LS_RECURSIVE("R") IF_FEATURE_LS_SORTFILES("rS") "s" \ + IF_FEATURE_AUTOWIDTH("T") IF_FEATURE_LS_TIMESTAMPS("tu") \ + IF_FEATURE_LS_SORTFILES("v") IF_FEATURE_AUTOWIDTH("w") "x" \ + IF_FEATURE_LS_SORTFILES("X") IF_FEATURE_HUMAN_READABLE("h") "k" \ + IF_SELINUX("K") "] [filenames...]" #define ls_full_usage "\n\n" \ "List directory contents\n" \ "\nOptions:" \ @@ -2347,49 +2347,49 @@ "\n -A Don't list . and .." \ "\n -a Don't hide entries starting with ." \ "\n -C List by columns" \ - USE_FEATURE_LS_TIMESTAMPS( \ + IF_FEATURE_LS_TIMESTAMPS( \ "\n -c With -l: sort by ctime") \ - USE_FEATURE_LS_COLOR( \ + IF_FEATURE_LS_COLOR( \ "\n --color[={always,never,auto}] Control coloring") \ "\n -d List directory entries instead of contents" \ - USE_FEATURE_LS_TIMESTAMPS( \ + IF_FEATURE_LS_TIMESTAMPS( \ "\n -e List full date and time") \ - USE_FEATURE_LS_FILETYPES( \ + IF_FEATURE_LS_FILETYPES( \ "\n -F Append indicator (one of */=@|) to entries") \ "\n -i List inode numbers" \ "\n -l Long listing format" \ "\n -n List numeric UIDs and GIDs instead of names" \ - USE_FEATURE_LS_FILETYPES( \ + IF_FEATURE_LS_FILETYPES( \ "\n -p Append indicator (one of /=@|) to entries") \ - USE_FEATURE_LS_FOLLOWLINKS( \ + IF_FEATURE_LS_FOLLOWLINKS( \ "\n -L List entries pointed to by symlinks") \ - USE_FEATURE_LS_RECURSIVE( \ + IF_FEATURE_LS_RECURSIVE( \ "\n -R List subdirectories recursively") \ - USE_FEATURE_LS_SORTFILES( \ + IF_FEATURE_LS_SORTFILES( \ "\n -r Sort in reverse order") \ - USE_FEATURE_LS_SORTFILES( \ + IF_FEATURE_LS_SORTFILES( \ "\n -S Sort by file size") \ "\n -s List the size of each file, in blocks" \ - USE_FEATURE_AUTOWIDTH( \ + IF_FEATURE_AUTOWIDTH( \ "\n -T NUM Assume tabstop every NUM columns") \ - USE_FEATURE_LS_TIMESTAMPS( \ + IF_FEATURE_LS_TIMESTAMPS( \ "\n -t With -l: sort by modification time") \ - USE_FEATURE_LS_TIMESTAMPS( \ + IF_FEATURE_LS_TIMESTAMPS( \ "\n -u With -l: sort by access time") \ - USE_FEATURE_LS_SORTFILES( \ + IF_FEATURE_LS_SORTFILES( \ "\n -v Sort by version") \ - USE_FEATURE_AUTOWIDTH( \ + IF_FEATURE_AUTOWIDTH( \ "\n -w NUM Assume the terminal is NUM columns wide") \ "\n -x List by lines" \ - USE_FEATURE_LS_SORTFILES( \ + IF_FEATURE_LS_SORTFILES( \ "\n -X Sort by extension") \ - USE_FEATURE_HUMAN_READABLE( \ + IF_FEATURE_HUMAN_READABLE( \ "\n -h List sizes in human readable format (1K 243M 2G)") \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -k List security context") \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -K List security context in long format") \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z List security context and permission") \ #define lsattr_trivial_usage \ @@ -2495,10 +2495,10 @@ #define md5sum_trivial_usage \ "[OPTION] [FILEs...]" \ - USE_FEATURE_MD5_SHA1_SUM_CHECK("\n or: md5sum [OPTION] -c [FILE]") + IF_FEATURE_MD5_SHA1_SUM_CHECK("\n or: md5sum [OPTION] -c [FILE]") #define md5sum_full_usage "\n\n" \ - "Print" USE_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " MD5 checksums" \ - USE_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ + "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " MD5 checksums" \ + IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ "\nOptions:" \ "\n -c Check sums against given list" \ "\n -s Don't output anything, status code shows success" \ @@ -2517,10 +2517,10 @@ #define sha1sum_trivial_usage \ "[OPTION] [FILEs...]" \ - USE_FEATURE_MD5_SHA1_SUM_CHECK("\n or: sha1sum [OPTION] -c [FILE]") + IF_FEATURE_MD5_SHA1_SUM_CHECK("\n or: sha1sum [OPTION] -c [FILE]") #define sha1sum_full_usage "\n\n" \ - "Print" USE_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums." \ - USE_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ + "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums." \ + IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ "\nOptions:" \ "\n -c Check sums against given list" \ "\n -s Don't output anything, status code shows success" \ @@ -2529,10 +2529,10 @@ #define sha256sum_trivial_usage \ "[OPTION] [FILEs...]" \ - USE_FEATURE_MD5_SHA1_SUM_CHECK("\n or: sha256sum [OPTION] -c [FILE]") + IF_FEATURE_MD5_SHA1_SUM_CHECK("\n or: sha256sum [OPTION] -c [FILE]") #define sha256sum_full_usage "\n\n" \ - "Print" USE_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums." \ - USE_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ + "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums." \ + IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ "\nOptions:" \ "\n -c Check sums against given list" \ "\n -s Don't output anything, status code shows success" \ @@ -2541,10 +2541,10 @@ #define sha512sum_trivial_usage \ "[OPTION] [FILEs...]" \ - USE_FEATURE_MD5_SHA1_SUM_CHECK("\n or: sha512sum [OPTION] -c [FILE]") + IF_FEATURE_MD5_SHA1_SUM_CHECK("\n or: sha512sum [OPTION] -c [FILE]") #define sha512sum_full_usage "\n\n" \ - "Print" USE_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums." \ - USE_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ + "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA1 checksums." \ + IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" \ "\nOptions:" \ "\n -c Check sums against given list" \ "\n -s Don't output anything, status code shows success" \ @@ -2558,19 +2558,19 @@ "\n" \ "It can be run by kernel as a hotplug helper. To activate it:\n" \ " echo /bin/mdev >/proc/sys/kernel/hotplug\n" \ - USE_FEATURE_MDEV_CONF( \ + IF_FEATURE_MDEV_CONF( \ "It uses /etc/mdev.conf with lines\n" \ "[-]DEVNAME UID:GID PERM" \ - USE_FEATURE_MDEV_RENAME(" [>|=PATH]") \ - USE_FEATURE_MDEV_EXEC(" [@|$|*COMMAND]") \ + IF_FEATURE_MDEV_RENAME(" [>|=PATH]") \ + IF_FEATURE_MDEV_EXEC(" [@|$|*COMMAND]") \ ) \ #define mdev_notes_usage "" \ - USE_FEATURE_MDEV_CONFIG( \ + IF_FEATURE_MDEV_CONFIG( \ "The mdev config file contains lines that look like:\n" \ " hd[a-z][0-9]* 0:3 660\n\n" \ "That's device name (with regex match), uid:gid, and permissions.\n\n" \ - USE_FEATURE_MDEV_EXEC( \ + IF_FEATURE_MDEV_EXEC( \ "Optionally, that can be followed (on the same line) by a special character\n" \ "and a command line to run after creating/before deleting the corresponding\n" \ "device(s). The environment variable $MDEV indicates the active device node\n" \ @@ -2610,7 +2610,7 @@ "\nOptions:" \ "\n -m Set permission mode (as in chmod), not rwxrwxrwx - umask" \ "\n -p No error if existing, make parent directories as needed" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Set security context" \ ) @@ -2659,7 +2659,7 @@ "Create named pipe (identical to 'mknod name p')\n" \ "\nOptions:" \ "\n -m MODE Mode (default a=rw)" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Set security context" \ ) @@ -2700,7 +2700,7 @@ "\n b: Make a block device" \ "\n c or u: Make a character device" \ "\n p: Make a named pipe (MAJOR and MINOR are ignored)" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Set security context" \ ) @@ -2745,7 +2745,7 @@ "[-knqrsv] MODULE [symbol=value...]" #define modprobe_full_usage "\n\n" \ "Options:" \ - USE_FEATURE_2_4_MODULES( \ + IF_FEATURE_2_4_MODULES( \ "\n -k Make module autoclean-able" \ ) \ "\n -n Dry run" \ @@ -2753,7 +2753,7 @@ "\n -r Remove module (stacks) or do autoclean" \ "\n -s Report via syslog instead of stderr" \ "\n -v Verbose" \ - USE_FEATURE_MODPROBE_BLACKLIST( \ + IF_FEATURE_MODPROBE_BLACKLIST( \ "\n -b Apply blacklist to module names too" \ ) @@ -2831,15 +2831,15 @@ "Mount a filesystem. Filesystem autodetection requires /proc be mounted.\n" \ "\nOptions:" \ "\n -a Mount all filesystems in fstab" \ - USE_FEATURE_MOUNT_FAKE( \ - USE_FEATURE_MTAB_SUPPORT( \ + IF_FEATURE_MOUNT_FAKE( \ + IF_FEATURE_MTAB_SUPPORT( \ "\n -f Update /etc/mtab, but don't mount" \ ) \ - SKIP_FEATURE_MTAB_SUPPORT( \ + IF_NOT_FEATURE_MTAB_SUPPORT( \ "\n -f Dry run" \ ) \ ) \ - USE_FEATURE_MTAB_SUPPORT( \ + IF_FEATURE_MTAB_SUPPORT( \ "\n -n Don't update /etc/mtab" \ ) \ "\n -r Read-only mount" \ @@ -2847,10 +2847,10 @@ "\n -t FSTYPE Filesystem type" \ "\n -O OPT Mount only filesystems with option OPT (-a only)" \ "\n-o OPT:" \ - USE_FEATURE_MOUNT_LOOP( \ + IF_FEATURE_MOUNT_LOOP( \ "\n loop Ignored (loop devices are autodetected)" \ ) \ - USE_FEATURE_MOUNT_FLAGS( \ + IF_FEATURE_MOUNT_FLAGS( \ "\n [a]sync Writes are [a]synchronous" \ "\n [no]atime Disable/enable updates to inode access times" \ "\n [no]diratime Disable/enable atime updates to directories" \ @@ -2945,26 +2945,26 @@ #endif #define nc_trivial_usage \ - USE_NC_EXTRA("[-iN] [-wN] ")USE_NC_SERVER("[-l] [-p PORT] ") \ - "["USE_NC_EXTRA("-f FILENAME|")"IPADDR PORTNUM]"USE_NC_EXTRA(" [-e COMMAND]") + IF_NC_EXTRA("[-iN] [-wN] ")IF_NC_SERVER("[-l] [-p PORT] ") \ + "["IF_NC_EXTRA("-f FILENAME|")"IPADDR PORTNUM]"IF_NC_EXTRA(" [-e COMMAND]") #define nc_full_usage "\n\n" \ - "Open a pipe to IP:port" USE_NC_EXTRA(" or file") \ + "Open a pipe to IP:port" IF_NC_EXTRA(" or file") \ NC_OPTIONS_STR \ - USE_NC_EXTRA( \ + IF_NC_EXTRA( \ "\n -e Exec rest of command line after connect" \ "\n -i SECS Delay interval for lines sent" \ "\n -w SECS Timeout for connect" \ "\n -f FILE Use file (ala /dev/ttyS0) instead of network" \ ) \ - USE_NC_SERVER( \ + IF_NC_SERVER( \ "\n -l Listen mode, for inbound connects" \ - USE_NC_EXTRA( \ + IF_NC_EXTRA( \ "\n (use -l twice with -e for persistent server)") \ "\n -p PORT Local port number" \ ) #define nc_notes_usage "" \ - USE_NC_EXTRA( \ + IF_NC_EXTRA( \ "To use netcat as a terminal emulator on a serial port:\n\n" \ "$ stty 115200 -F /dev/ttyS0\n" \ "$ stty raw -echo -ctlecho && nc -f /dev/ttyS0\n" \ @@ -2984,12 +2984,12 @@ #define nc_trivial_usage \ "[-options] hostname port - connect" \ - USE_NC_SERVER("\n" \ + IF_NC_SERVER("\n" \ "nc [-options] -l -p port [hostname] [port] - listen") #define nc_full_usage "\n\n" \ "Options:" \ "\n -e prog [args] Program to exec after connect (must be last)" \ - USE_NC_SERVER( \ + IF_NC_SERVER( \ "\n -l Listen mode, for inbound connects" \ ) \ "\n -n Don't do DNS resolution" \ @@ -2998,7 +2998,7 @@ "\n -u UDP mode" \ "\n -v Verbose (cumulative: -vv)" \ "\n -w secs Timeout for connects and final net reads" \ - USE_NC_EXTRA( \ + IF_NC_EXTRA( \ "\n -i sec Delay interval for lines sent" /* ", ports scanned" */ \ "\n -o file Hex dump of traffic" \ "\n -z Zero-I/O mode (scanning)" \ @@ -3011,7 +3011,7 @@ #endif #define netstat_trivial_usage \ - "[-laentuwxr"USE_FEATURE_NETSTAT_WIDE("W")USE_FEATURE_NETSTAT_PRG("p")"]" + "[-laentuwxr"IF_FEATURE_NETSTAT_WIDE("W")IF_FEATURE_NETSTAT_PRG("p")"]" #define netstat_full_usage "\n\n" \ "Display networking information\n" \ "\nOptions:" \ @@ -3024,10 +3024,10 @@ "\n -w Raw sockets" \ "\n -x Unix sockets" \ "\n -r Display routing table" \ - USE_FEATURE_NETSTAT_WIDE( \ + IF_FEATURE_NETSTAT_WIDE( \ "\n -W Display with no column truncation" \ ) \ - USE_FEATURE_NETSTAT_PRG( \ + IF_FEATURE_NETSTAT_PRG( \ "\n -p Display PID/Program name for sockets" \ ) @@ -3084,7 +3084,7 @@ "Address: 127.0.0.1\n" #define od_trivial_usage \ - "[-aBbcDdeFfHhIiLlOovXx] " USE_DESKTOP("[-t TYPE] ") "[FILE]" + "[-aBbcDdeFfHhIiLlOovXx] " IF_DESKTOP("[-t TYPE] ") "[FILE]" #define od_full_usage "\n\n" \ "Write an unambiguous representation, octal bytes by default, of FILE\n" \ "to standard output. With no FILE or when FILE is -, read standard input." @@ -3119,16 +3119,16 @@ "\n -u Unlock (re-enable) account" \ #define chpasswd_trivial_usage \ - USE_GETOPT_LONG("[--md5|--encrypted]") SKIP_GETOPT_LONG("[-m|-e]") + IF_GETOPT_LONG("[--md5|--encrypted]") IF_NOT_GETOPT_LONG("[-m|-e]") #define chpasswd_full_usage "\n\n" \ "Read user:password information from stdin " \ "and update /etc/passwd accordingly.\n" \ "\nOptions:" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ "\n -e,--encrypted Supplied passwords are in encrypted form" \ "\n -m,--md5 Use MD5 encryption instead of DES" \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ "\n -e Supplied passwords are in encrypted form" \ "\n -m Use MD5 encryption instead of DES" \ ) @@ -3168,18 +3168,18 @@ #define pidof_full_usage "\n\n" \ "List PIDs of all processes with names that match NAMEs" \ USAGE_PIDOF \ - USE_FEATURE_PIDOF_SINGLE( \ + IF_FEATURE_PIDOF_SINGLE( \ "\n -s Show only one PID") \ - USE_FEATURE_PIDOF_OMIT( \ + IF_FEATURE_PIDOF_OMIT( \ "\n -o PID Omit given pid" \ "\n Use %PPID to omit pid of pidof's parent") \ #define pidof_example_usage \ "$ pidof init\n" \ "1\n" \ - USE_FEATURE_PIDOF_OMIT( \ + IF_FEATURE_PIDOF_OMIT( \ "$ pidof /bin/sh\n20351 5973 5950\n") \ - USE_FEATURE_PIDOF_OMIT( \ + IF_FEATURE_PIDOF_OMIT( \ "$ pidof /bin/sh -o %PPID\n20351 5950") #if !ENABLE_FEATURE_FANCY_PING @@ -3273,7 +3273,7 @@ "\n -T Get messages with TOP instead with RETR" \ "\n -k Keep retrieved messages on the server" \ "\n -t timeout Set network timeout" \ - USE_FEATURE_POPMAILDIR_DELIVERY( \ + IF_FEATURE_POPMAILDIR_DELIVERY( \ "\n -F \"program arg1 arg2 ...\" Filter by program. May be multiple" \ "\n -M \"program arg1 arg2 ...\" Deliver by program" \ ) \ @@ -3332,10 +3332,10 @@ #define ps_full_usage "\n\n" \ "Report process status\n" \ USAGE_PS \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Show SE Linux context" \ ) \ - USE_FEATURE_PS_WIDE( \ + IF_FEATURE_PS_WIDE( \ "\n w Wide output" \ ) @@ -3404,10 +3404,10 @@ "files do not block on disk I/O" #define readlink_trivial_usage \ - USE_FEATURE_READLINK_FOLLOW("[-f] ") "FILE" + IF_FEATURE_READLINK_FOLLOW("[-f] ") "FILE" #define readlink_full_usage "\n\n" \ "Display the value of a symlink" \ - USE_FEATURE_READLINK_FOLLOW( "\n" \ + IF_FEATURE_READLINK_FOLLOW( "\n" \ "\nOptions:" \ "\n -f Canonicalize by following all symlinks") \ @@ -3505,11 +3505,11 @@ #define rmdir_full_usage "\n\n" \ "Remove the DIRECTORY, if it is empty.\n" \ "\nOptions:" \ - USE_FEATURE_RMDIR_LONG_OPTIONS( \ + IF_FEATURE_RMDIR_LONG_OPTIONS( \ "\n -p|--parents Include parents" \ "\n -ignore-fail-on-non-empty" \ ) \ - SKIP_FEATURE_RMDIR_LONG_OPTIONS( \ + IF_NOT_FEATURE_RMDIR_LONG_OPTIONS( \ "\n -p Include parents" \ ) @@ -3535,7 +3535,7 @@ "\nOptions:" \ "\n -n Don't resolve names" \ "\n -e Display other/more information" \ - "\n -A inet" USE_FEATURE_IPV6("{6}") " Select address family" \ + "\n -A inet" IF_FEATURE_IPV6("{6}") " Select address family" \ #define rpm_trivial_usage \ "-i -q[ildc]p package.rpm" @@ -3559,7 +3559,7 @@ "[-a | -l | -u] [-d DEV] [-m MODE] [-s SEC | -t TIME]" #define rtcwake_full_usage "\n\n" \ "Enter a system sleep state until specified wakeup time\n" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ "\n -a,--auto Read clock mode from adjtime" \ "\n -l,--local Clock is set to local time" \ "\n -u,--utc Clock is set to UTC time" \ @@ -3568,7 +3568,7 @@ "\n -s,--seconds=SEC Set the timeout in SEC seconds from now" \ "\n -t,--time=TIME Set the timeout to TIME seconds from epoch" \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ "\n -a Read clock mode from adjtime" \ "\n -l Clock is set to local time" \ "\n -u Clock is set to UTC time" \ @@ -3584,14 +3584,14 @@ #define runcon_full_usage "\n\n" \ "Run a program in a different security context\n" \ "\n CONTEXT Complete security context\n" \ - USE_FEATURE_RUNCON_LONG_OPTIONS( \ + IF_FEATURE_RUNCON_LONG_OPTIONS( \ "\n -c,--compute Compute process transition context before modifying" \ "\n -t,--type=TYPE Type (for same role as parent)" \ "\n -u,--user=USER User identity" \ "\n -r,--role=ROLE Role" \ "\n -l,--range=RNG Levelrange" \ ) \ - SKIP_FEATURE_RUNCON_LONG_OPTIONS( \ + IF_NOT_FEATURE_RUNCON_LONG_OPTIONS( \ "\n -c Compute process transition context before modifying" \ "\n -t TYPE Type (for same role as parent)" \ "\n -u USER User identity" \ @@ -3600,14 +3600,14 @@ ) #define run_parts_trivial_usage \ - "[-t] "USE_FEATURE_RUN_PARTS_FANCY("[-l] ")"[-a ARG] [-u MASK] DIRECTORY" + "[-t] "IF_FEATURE_RUN_PARTS_FANCY("[-l] ")"[-a ARG] [-u MASK] DIRECTORY" #define run_parts_full_usage "\n\n" \ "Run a bunch of scripts in a directory\n" \ "\nOptions:" \ "\n -t Print what would be run, but don't actually run anything" \ "\n -a ARG Pass ARG as argument for every program" \ "\n -u MASK Set the umask to MASK before running every program" \ - USE_FEATURE_RUN_PARTS_FANCY( \ + IF_FEATURE_RUN_PARTS_FANCY( \ "\n -l Print names of all matching files even if they are not executable" \ ) @@ -3728,7 +3728,7 @@ "\n -b Display current state of booleans" \ #define setconsole_trivial_usage \ - "[-r" USE_FEATURE_SETCONSOLE_LONG_OPTIONS("|--reset") "] [DEVICE]" + "[-r" IF_FEATURE_SETCONSOLE_LONG_OPTIONS("|--reset") "] [DEVICE]" #define setconsole_full_usage "\n\n" \ "Redirect system console output to DEVICE (default: /dev/tty)\n" \ "\nOptions:" \ @@ -3740,13 +3740,13 @@ #define setfiles_trivial_usage \ "[-dnpqsvW] [-e dir]... [-o file] [-r alt_root_path]" \ - USE_FEATURE_SETFILES_CHECK_OPTION( \ + IF_FEATURE_SETFILES_CHECK_OPTION( \ " [-c policyfile] spec_file" \ ) \ " pathname" #define setfiles_full_usage "\n\n" \ "Reset file contexts under pathname according to spec_file\n" \ - USE_FEATURE_SETFILES_CHECK_OPTION( \ + IF_FEATURE_SETFILES_CHECK_OPTION( \ "\n -c file Check the validity of the contexts against the specified binary policy" \ ) \ "\n -d Show which specification matched each file" \ @@ -3809,10 +3809,10 @@ "lash is deprecated, please use hush" #define last_trivial_usage \ - ""USE_FEATURE_LAST_FANCY("[-HW] [-f file]") + ""IF_FEATURE_LAST_FANCY("[-HW] [-f file]") #define last_full_usage "\n\n" \ "Show listing of the last users that logged into the system" \ - USE_FEATURE_LAST_FANCY( "\n" \ + IF_FEATURE_LAST_FANCY( "\n" \ "\nOptions:" \ /* "\n -H Show header line" */ \ "\n -W Display with no host column truncation" \ @@ -3843,27 +3843,27 @@ "\n -F Disable RTS/CTS flow control" \ #define sleep_trivial_usage \ - USE_FEATURE_FANCY_SLEEP("[") "N" USE_FEATURE_FANCY_SLEEP("]...") + IF_FEATURE_FANCY_SLEEP("[") "N" IF_FEATURE_FANCY_SLEEP("]...") #define sleep_full_usage "\n\n" \ - SKIP_FEATURE_FANCY_SLEEP("Pause for N seconds") \ - USE_FEATURE_FANCY_SLEEP( \ + IF_NOT_FEATURE_FANCY_SLEEP("Pause for N seconds") \ + IF_FEATURE_FANCY_SLEEP( \ "Pause for a time equal to the total of the args given, where each arg can\n" \ "have an optional suffix of (s)econds, (m)inutes, (h)ours, or (d)ays") #define sleep_example_usage \ "$ sleep 2\n" \ "[2 second delay results]\n" \ - USE_FEATURE_FANCY_SLEEP( \ + IF_FEATURE_FANCY_SLEEP( \ "$ sleep 1d 3h 22m 8s\n" \ "[98528 second delay results]\n") #define sort_trivial_usage \ "[-nru" \ - USE_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") \ + IF_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") \ "] [FILE]..." #define sort_full_usage "\n\n" \ "Sort lines of text\n" \ "\nOptions:" \ - USE_FEATURE_SORT_BIG( \ + IF_FEATURE_SORT_BIG( \ "\n -b Ignore leading blanks" \ "\n -c Check whether input is sorted" \ "\n -d Dictionary order (blank or alphanumeric only)" \ @@ -3874,17 +3874,17 @@ "\n -M Sort month" \ ) \ "\n -n Sort numbers" \ - USE_FEATURE_SORT_BIG( \ + IF_FEATURE_SORT_BIG( \ "\n -o Output to file" \ "\n -k Sort by key" \ "\n -t CHAR Key separator" \ ) \ "\n -r Reverse sort order" \ - USE_FEATURE_SORT_BIG( \ + IF_FEATURE_SORT_BIG( \ "\n -s Stable (don't sort ties alphabetically)" \ ) \ "\n -u Suppress duplicate lines" \ - USE_FEATURE_SORT_BIG( \ + IF_FEATURE_SORT_BIG( \ "\n -z Lines are terminated by NUL, not newline" \ "\n -mST Ignored for GNU compatibility") \ @@ -3896,7 +3896,7 @@ "d\n" \ "e\n" \ "f\n" \ - USE_FEATURE_SORT_BIG( \ + IF_FEATURE_SORT_BIG( \ "$ echo -e \"c 3\\nb 2\\nd 2\" | $SORT -k 2,2n -k 1,1r\n" \ "d 2\n" \ "b 2\n" \ @@ -3922,7 +3922,7 @@ "Search for matching processes, and then\n" \ "-K: stop all matching processes.\n" \ "-S: start a process unless a matching process is found.\n" \ - USE_FEATURE_START_STOP_DAEMON_LONG_OPTIONS( \ + IF_FEATURE_START_STOP_DAEMON_LONG_OPTIONS( \ "\nProcess matching:" \ "\n -u,--user USERNAME|UID Match only this user's processes" \ "\n -n,--name NAME Match processes with NAME" \ @@ -3935,7 +3935,7 @@ "\n -x,--exec EXECUTABLE Program to run" \ "\n -a,--startas NAME Zeroth argument" \ "\n -b,--background Background" \ - USE_FEATURE_START_STOP_DAEMON_FANCY( \ + IF_FEATURE_START_STOP_DAEMON_FANCY( \ "\n -N,--nicelevel N Change nice level" \ ) \ "\n -c,--chuid USER[:[GRP]] Change to user/group" \ @@ -3944,13 +3944,13 @@ "\n -s,--signal SIG Signal to send" \ "\n -t,--test Match only, exit with 0 if a process is found" \ "\nOther:" \ - USE_FEATURE_START_STOP_DAEMON_FANCY( \ + IF_FEATURE_START_STOP_DAEMON_FANCY( \ "\n -o,--oknodo Exit with status 0 if nothing is done" \ "\n -v,--verbose Verbose" \ ) \ "\n -q,--quiet Quiet" \ ) \ - SKIP_FEATURE_START_STOP_DAEMON_LONG_OPTIONS( \ + IF_NOT_FEATURE_START_STOP_DAEMON_LONG_OPTIONS( \ "\nProcess matching:" \ "\n -u USERNAME|UID Match only this user's processes" \ "\n -n NAME Match processes with NAME" \ @@ -3963,7 +3963,7 @@ "\n -x EXECUTABLE Program to run" \ "\n -a NAME Zeroth argument" \ "\n -b Background" \ - USE_FEATURE_START_STOP_DAEMON_FANCY( \ + IF_FEATURE_START_STOP_DAEMON_FANCY( \ "\n -N N Change nice level" \ ) \ "\n -c USER[:[GRP]] Change to user/group" \ @@ -3972,7 +3972,7 @@ "\n -s SIG Signal to send" \ "\n -t Match only, exit with 0 if a process is found" \ "\nOther:" \ - USE_FEATURE_START_STOP_DAEMON_FANCY( \ + IF_FEATURE_START_STOP_DAEMON_FANCY( \ "\n -o Exit with status 0 if nothing is done" \ "\n -v Verbose" \ ) \ @@ -3984,16 +3984,16 @@ #define stat_full_usage "\n\n" \ "Display file (default) or filesystem status\n" \ "\nOptions:" \ - USE_FEATURE_STAT_FORMAT( \ + IF_FEATURE_STAT_FORMAT( \ "\n -c fmt Use the specified format" \ ) \ "\n -f Display filesystem status" \ "\n -L Dereference links" \ "\n -t Display info in terse form" \ - USE_SELINUX( \ + IF_SELINUX( \ "\n -Z Print security context" \ ) \ - USE_FEATURE_STAT_FORMAT( \ + IF_FEATURE_STAT_FORMAT( \ "\n\nValid format sequences for files:\n" \ " %a Access rights in octal\n" \ " %A Access rights in human readable form\n" \ @@ -4027,7 +4027,7 @@ " %c Total file nodes in file system\n" \ " %d Free file nodes in file system\n" \ " %f Free blocks in file system\n" \ - USE_SELINUX( \ + IF_SELINUX( \ " %C Security context in SELinux\n" \ ) \ " %i File System ID in hex\n" \ @@ -4115,12 +4115,12 @@ "\n -a Stop swapping on all swap devices" \ #define swapon_trivial_usage \ - "[-a]" USE_FEATURE_SWAPON_PRI(" [-p pri]") " [DEVICE]" + "[-a]" IF_FEATURE_SWAPON_PRI(" [-p pri]") " [DEVICE]" #define swapon_full_usage "\n\n" \ "Start swapping on DEVICE\n" \ "\nOptions:" \ "\n -a Start swapping on all swap devices" \ - USE_FEATURE_SWAPON_PRI( \ + IF_FEATURE_SWAPON_PRI( \ "\n -p pri Set swap device priority" \ ) \ @@ -4166,15 +4166,15 @@ "\n -O FILE Log to given file (default=/var/log/messages)" \ "\n -l n Set local log level" \ "\n -S Smaller logging output" \ - USE_FEATURE_ROTATE_LOGFILE( \ + IF_FEATURE_ROTATE_LOGFILE( \ "\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \ "\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \ - USE_FEATURE_REMOTE_LOG( \ + IF_FEATURE_REMOTE_LOG( \ "\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \ "\n -L Log locally and via network (default is network only if -R)") \ - USE_FEATURE_SYSLOGD_DUP( \ + IF_FEATURE_SYSLOGD_DUP( \ "\n -D Drop duplicates") \ - USE_FEATURE_IPC_SYSLOG( \ + IF_FEATURE_IPC_SYSLOG( \ "\n -C[size(KiB)] Log to shared mem buffer (read it using logread)") \ /* NB: -Csize shouldn't have space (because size is optional) */ /* "\n -m MIN Minutes between MARK lines (default=20, 0=off)" */ @@ -4195,11 +4195,11 @@ "With more than one FILE, precede each with a header giving the\n" \ "file name. With no FILE, or when FILE is -, read standard input.\n" \ "\nOptions:" \ - USE_FEATURE_FANCY_TAIL( \ + IF_FEATURE_FANCY_TAIL( \ "\n -c N[kbm] Output the last N bytes") \ "\n -n N[kbm] Print last N lines instead of last 10" \ "\n -f Output data as the file grows" \ - USE_FEATURE_FANCY_TAIL( \ + IF_FEATURE_FANCY_TAIL( \ "\n -q Never output headers giving file names" \ "\n -s SEC Wait SEC seconds between reads with -f" \ "\n -v Always output headers giving file names" \ @@ -4213,35 +4213,35 @@ "nameserver 10.0.0.1\n" #define tar_trivial_usage \ - "-[" USE_FEATURE_TAR_CREATE("c") USE_FEATURE_SEAMLESS_GZ("z") \ - USE_FEATURE_SEAMLESS_BZ2("j") USE_FEATURE_SEAMLESS_LZMA("a") \ - USE_FEATURE_SEAMLESS_Z("Z") "xtvO] " \ - USE_FEATURE_TAR_FROM("[-X FILE] ") \ + "-[" IF_FEATURE_TAR_CREATE("c") IF_FEATURE_SEAMLESS_GZ("z") \ + IF_FEATURE_SEAMLESS_BZ2("j") IF_FEATURE_SEAMLESS_LZMA("a") \ + IF_FEATURE_SEAMLESS_Z("Z") "xtvO] " \ + IF_FEATURE_TAR_FROM("[-X FILE] ") \ "[-f TARFILE] [-C DIR] [FILE(s)]..." #define tar_full_usage "\n\n" \ "Create, extract, or list files from a tar file\n" \ "\nOptions:" \ - USE_FEATURE_TAR_CREATE( \ + IF_FEATURE_TAR_CREATE( \ "\n c Create") \ "\n x Extract" \ "\n t List" \ "\nArchive format selection:" \ - USE_FEATURE_SEAMLESS_GZ( \ + IF_FEATURE_SEAMLESS_GZ( \ "\n z Filter the archive through gzip" \ ) \ - USE_FEATURE_SEAMLESS_BZ2( \ + IF_FEATURE_SEAMLESS_BZ2( \ "\n j Filter the archive through bzip2" \ ) \ - USE_FEATURE_SEAMLESS_LZMA( \ + IF_FEATURE_SEAMLESS_LZMA( \ "\n a Filter the archive through lzma" \ ) \ - USE_FEATURE_SEAMLESS_Z( \ + IF_FEATURE_SEAMLESS_Z( \ "\n Z Filter the archive through compress" \ ) \ "\nFile selection:" \ "\n f Name of TARFILE or \"-\" for stdin" \ "\n O Extract to stdout" \ - USE_FEATURE_TAR_FROM( \ + IF_FEATURE_TAR_FROM( \ "\n exclude File to exclude" \ "\n X File with names to exclude" \ ) \ @@ -4303,13 +4303,13 @@ "[OPTION]" #define telnetd_full_usage "\n\n" \ "Handle incoming telnet connections" \ - SKIP_FEATURE_TELNETD_STANDALONE(" via inetd") "\n" \ + IF_NOT_FEATURE_TELNETD_STANDALONE(" via inetd") "\n" \ "\nOptions:" \ "\n -l LOGIN Exec LOGIN on connect" \ "\n -f issue_file Display issue_file instead of /etc/issue" \ "\n -K Close connection as soon as login exits" \ "\n (normally wait until all programs close slave pty)" \ - USE_FEATURE_TELNETD_STANDALONE( \ + IF_FEATURE_TELNETD_STANDALONE( \ "\n -p PORT Port to listen on" \ "\n -b ADDR Address to bind to" \ "\n -F Run in foreground" \ @@ -4343,11 +4343,11 @@ "OBJECT: {qdisc|class|filter}\n" \ "CMD: {add|del|change|replace|show}\n" \ "\n" \ - "qdisc [ handle QHANDLE ] [ root |"USE_FEATURE_TC_INGRESS(" ingress |")" parent CLASSID ]\n" \ + "qdisc [ handle QHANDLE ] [ root |"IF_FEATURE_TC_INGRESS(" ingress |")" parent CLASSID ]\n" \ /* "\t[ estimator INTERVAL TIME_CONSTANT ]\n" */ \ "\t[ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" \ "\tQDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n" \ - "qdisc show [ dev STRING ]"USE_FEATURE_TC_INGRESS(" [ingress]")"\n" \ + "qdisc show [ dev STRING ]"IF_FEATURE_TC_INGRESS(" [ingress]")"\n" \ "class [ classid CLASSID ] [ root | parent CLASSID ]\n" \ "\t[ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" \ "class show [ dev STRING ] [ root | parent CLASSID ]\n" \ @@ -4401,13 +4401,13 @@ "\nOptions:" \ "\n -l FILE Local FILE" \ "\n -r FILE Remote FILE" \ - USE_FEATURE_TFTP_GET( \ + IF_FEATURE_TFTP_GET( \ "\n -g Get file" \ ) \ - USE_FEATURE_TFTP_PUT( \ + IF_FEATURE_TFTP_PUT( \ "\n -p Put file" \ ) \ - USE_FEATURE_TFTP_BLOCKSIZE( \ + IF_FEATURE_TFTP_BLOCKSIZE( \ "\n -b SIZE Transfer blocks of SIZE octets" \ ) @@ -4512,7 +4512,7 @@ "" #define tty_full_usage "\n\n" \ "Print file name of standard input's terminal" \ - USE_INCLUDE_SUSv2( "\n" \ + IF_INCLUDE_SUSv2( "\n" \ "\nOptions:" \ "\n -s Print nothing, only return exit status" \ ) @@ -4526,14 +4526,14 @@ "Print dimension(s) of standard input's terminal, on error return 80x25" #define tunctl_trivial_usage \ - "[-f device] ([-t name] | -d name)" USE_FEATURE_TUNCTL_UG(" [-u owner] [-g group] [-b]") + "[-f device] ([-t name] | -d name)" IF_FEATURE_TUNCTL_UG(" [-u owner] [-g group] [-b]") #define tunctl_full_usage "\n\n" \ "Create or delete tun interfaces" \ "\nOptions:" \ "\n -f name tun device (/dev/net/tun)" \ "\n -t name Create iface 'name'" \ "\n -d name Delete iface 'name'" \ -USE_FEATURE_TUNCTL_UG( \ +IF_FEATURE_TUNCTL_UG( \ "\n -u owner Set iface owner" \ "\n -g group Set iface group" \ "\n -b Brief output" \ @@ -4554,9 +4554,9 @@ #define udhcpc_trivial_usage \ "[-Cfbnqtvo] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \ - " [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..." USE_FEATURE_UDHCP_PORT(" [-P N]") + " [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..." IF_FEATURE_UDHCP_PORT(" [-P N]") #define udhcpc_full_usage "\n\n" \ - USE_GETOPT_LONG( \ + IF_GETOPT_LONG( \ " -V,--vendorclass=CLASSID Vendor class identifier" \ "\n -i,--interface=INTERFACE Interface to use (default eth0)" \ "\n -H,-h,--hostname=HOSTNAME Client hostname" \ @@ -4578,14 +4578,14 @@ "\n -n,--now Exit with failure if lease is not immediately obtained" \ "\n -q,--quit Quit after obtaining lease" \ "\n -R,--release Release IP on quit" \ - USE_FEATURE_UDHCP_PORT( \ + IF_FEATURE_UDHCP_PORT( \ "\n -P,--client-port N Use port N instead of default 68" \ ) \ - USE_FEATURE_UDHCPC_ARPING( \ + IF_FEATURE_UDHCPC_ARPING( \ "\n -a,--arping Use arping to validate offered address" \ ) \ ) \ - SKIP_GETOPT_LONG( \ + IF_NOT_GETOPT_LONG( \ " -V CLASSID Vendor class identifier" \ "\n -i INTERFACE Interface to use (default: eth0)" \ "\n -H,-h HOSTNAME Client hostname" \ @@ -4607,22 +4607,22 @@ "\n -n Exit with failure if lease is not immediately obtained" \ "\n -q Quit after obtaining lease" \ "\n -R Release IP on quit" \ - USE_FEATURE_UDHCP_PORT( \ + IF_FEATURE_UDHCP_PORT( \ "\n -P N Use port N instead of default 68" \ ) \ - USE_FEATURE_UDHCPC_ARPING( \ + IF_FEATURE_UDHCPC_ARPING( \ "\n -a Use arping to validate offered address" \ ) \ ) #define udhcpd_trivial_usage \ - "[-fS]" USE_FEATURE_UDHCP_PORT(" [-P N]") " [configfile]" \ + "[-fS]" IF_FEATURE_UDHCP_PORT(" [-P N]") " [configfile]" \ #define udhcpd_full_usage "\n\n" \ "DHCP server\n" \ "\n -f Run in foreground" \ "\n -S Log to syslog too" \ - USE_FEATURE_UDHCP_PORT( \ + IF_FEATURE_UDHCP_PORT( \ "\n -P N Use port N instead of default 67" \ ) @@ -4631,16 +4631,16 @@ #define umount_full_usage "\n\n" \ "Unmount file systems\n" \ "\nOptions:" \ - USE_FEATURE_UMOUNT_ALL( \ - "\n -a Unmount all file systems" USE_FEATURE_MTAB_SUPPORT(" in /etc/mtab") \ + IF_FEATURE_UMOUNT_ALL( \ + "\n -a Unmount all file systems" IF_FEATURE_MTAB_SUPPORT(" in /etc/mtab") \ ) \ - USE_FEATURE_MTAB_SUPPORT( \ + IF_FEATURE_MTAB_SUPPORT( \ "\n -n Don't erase /etc/mtab entries" \ ) \ "\n -r Try to remount devices as read-only if mount is busy" \ "\n -l Lazy umount (detach filesystem)" \ "\n -f Force umount (i.e., unreachable NFS server)" \ - USE_FEATURE_MOUNT_LOOP( \ + IF_FEATURE_MOUNT_LOOP( \ "\n -d Free loop device if it has been used" \ ) @@ -4677,12 +4677,12 @@ #define unexpand_full_usage "\n\n" \ "Convert spaces to tabs, writing to standard output.\n" \ "\nOptions:" \ - USE_FEATURE_UNEXPAND_LONG_OPTIONS( \ + IF_FEATURE_UNEXPAND_LONG_OPTIONS( \ "\n -a,--all Convert all blanks" \ "\n -f,--first-only Convert only leading blanks" \ "\n -t,--tabs=N Tabstops every N chars" \ ) \ - SKIP_FEATURE_UNEXPAND_LONG_OPTIONS( \ + IF_NOT_FEATURE_UNEXPAND_LONG_OPTIONS( \ "\n -a Convert all blanks" \ "\n -f Convert only leading blanks" \ "\n -t N Tabstops every N chars" \ @@ -4788,9 +4788,9 @@ #define vi_full_usage "\n\n" \ "Edit FILE\n" \ "\nOptions:" \ - USE_FEATURE_VI_COLON( \ + IF_FEATURE_VI_COLON( \ "\n -c Initial command to run ($EXINIT also available)") \ - USE_FEATURE_VI_READONLY( \ + IF_FEATURE_VI_READONLY( \ "\n -R Read-only - do not write to the file") \ "\n -H Short help regarding available features" \ @@ -4842,12 +4842,12 @@ " 31 46 1365 /etc/passwd\n" #define wget_trivial_usage \ - USE_FEATURE_WGET_LONG_OPTIONS( \ + IF_FEATURE_WGET_LONG_OPTIONS( \ "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document file]\n" \ " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" \ " [-U|--user-agent agent] url" \ ) \ - SKIP_FEATURE_WGET_LONG_OPTIONS( \ + IF_NOT_FEATURE_WGET_LONG_OPTIONS( \ "[-csq] [-O file] [-Y on/off] [-P DIR] [-U agent] url" \ ) #define wget_full_usage "\n\n" \ @@ -4886,16 +4886,16 @@ #define xargs_full_usage "\n\n" \ "Execute COMMAND on every item given by standard input\n" \ "\nOptions:" \ - USE_FEATURE_XARGS_SUPPORT_CONFIRMATION( \ + IF_FEATURE_XARGS_SUPPORT_CONFIRMATION( \ "\n -p Ask user whether to run each command") \ "\n -r Do not run command if input is empty" \ - USE_FEATURE_XARGS_SUPPORT_ZERO_TERM( \ + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( \ "\n -0 Input is separated by NUL characters") \ "\n -t Print the command on stderr before execution" \ "\n -e[STR] STR stops input processing" \ "\n -n N Pass no more than N args to COMMAND" \ "\n -s N Pass command line of no more than N bytes" \ - USE_FEATURE_XARGS_SUPPORT_TERMOPT( \ + IF_FEATURE_XARGS_SUPPORT_TERMOPT( \ "\n -x Exit if size is exceeded") \ #define xargs_example_usage \ Index: include/applets.h =================================================================== --- include/applets.h (revision 26172) +++ include/applets.h (revision 26173) @@ -67,358 +67,358 @@ #endif -USE_TEST(APPLET_NOFORK([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test)) -USE_TEST(APPLET_NOFORK([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test)) -USE_ACPID(APPLET(acpid, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_AR(APPLET(ar, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_ARP(APPLET(arp, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_ARPING(APPLET(arping, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_ASH(APPLET(ash, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_AWK(APPLET_NOEXEC(awk, awk, _BB_DIR_USR_BIN, _BB_SUID_NEVER, awk)) -USE_BASENAME(APPLET_NOFORK(basename, basename, _BB_DIR_USR_BIN, _BB_SUID_NEVER, basename)) -USE_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_NEVER)) -//USE_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_BLKID(APPLET(blkid, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_BRCTL(APPLET(brctl, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat)) -USE_BZIP2(APPLET(bzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CAL(APPLET(cal, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CAT(APPLET_NOFORK(cat, cat, _BB_DIR_BIN, _BB_SUID_NEVER, cat)) -USE_CATV(APPLET(catv, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_CHAT(APPLET(chat, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CHATTR(APPLET(chattr, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_CHCON(APPLET(chcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CHGRP(APPLET_NOEXEC(chgrp, chgrp, _BB_DIR_BIN, _BB_SUID_NEVER, chgrp)) -USE_CHMOD(APPLET_NOEXEC(chmod, chmod, _BB_DIR_BIN, _BB_SUID_NEVER, chmod)) -USE_CHOWN(APPLET_NOEXEC(chown, chown, _BB_DIR_BIN, _BB_SUID_NEVER, chown)) -USE_CHPASSWD(APPLET(chpasswd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_CHPST(APPLET(chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CHROOT(APPLET(chroot, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_CHRT(APPLET(chrt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CHVT(APPLET(chvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CKSUM(APPLET(cksum, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CLEAR(APPLET(clear, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CMP(APPLET(cmp, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_COMM(APPLET(comm, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CP(APPLET_NOEXEC(cp, cp, _BB_DIR_BIN, _BB_SUID_NEVER, cp)) -USE_CPIO(APPLET(cpio, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_CROND(APPLET(crond, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_CRONTAB(APPLET(crontab, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) -USE_CRYPTPW(APPLET(cryptpw, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_CTTYHACK(APPLET(cttyhack, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_CUT(APPLET_NOEXEC(cut, cut, _BB_DIR_USR_BIN, _BB_SUID_NEVER, cut)) -USE_DATE(APPLET(date, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_DC(APPLET(dc, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_DD(APPLET_NOEXEC(dd, dd, _BB_DIR_BIN, _BB_SUID_NEVER, dd)) -USE_DEALLOCVT(APPLET(deallocvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_DELGROUP(APPLET_ODDNAME(delgroup, deluser, _BB_DIR_BIN, _BB_SUID_NEVER, delgroup)) -USE_DELUSER(APPLET(deluser, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_DEPMOD(APPLET(depmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) -USE_DEVFSD(APPLET(devfsd, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_DEVMEM(APPLET(devmem, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_DF(APPLET(df, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_APP_DHCPRELAY(APPLET(dhcprelay, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_DIFF(APPLET(diff, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_DIRNAME(APPLET_NOFORK(dirname, dirname, _BB_DIR_USR_BIN, _BB_SUID_NEVER, dirname)) -USE_DMESG(APPLET(dmesg, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_DNSD(APPLET(dnsd, _BB_DIR_USR_SBIN, _BB_SUID_ALWAYS)) -USE_DOS2UNIX(APPLET(dos2unix, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_DPKG(APPLET(dpkg, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, _BB_DIR_USR_BIN, _BB_SUID_NEVER, dpkg_deb)) -USE_DU(APPLET(du, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_DUMPKMAP(APPLET(dumpkmap, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_APP_DUMPLEASES(APPLET(dumpleases, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -//USE_E2FSCK(APPLET(e2fsck, _BB_DIR_SBIN, _BB_SUID_NEVER)) -//USE_E2LABEL(APPLET_ODDNAME(e2label, tune2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, e2label)) -USE_ECHO(APPLET_NOFORK(echo, echo, _BB_DIR_BIN, _BB_SUID_NEVER, echo)) -USE_ED(APPLET(ed, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_FEATURE_GREP_EGREP_ALIAS(APPLET_ODDNAME(egrep, grep, _BB_DIR_BIN, _BB_SUID_NEVER, egrep)) -USE_EJECT(APPLET(eject, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_ENV(APPLET_NOEXEC(env, env, _BB_DIR_USR_BIN, _BB_SUID_NEVER, env)) -USE_ENVDIR(APPLET_ODDNAME(envdir, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, envdir)) -USE_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, envuidgid)) -USE_ETHER_WAKE(APPLET_ODDNAME(ether-wake, ether_wake, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ether_wake)) -USE_EXPAND(APPLET(expand, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_EXPR(APPLET(expr, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_FAKEIDENTD(APPLET(fakeidentd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_FALSE(APPLET_NOFORK(false, false, _BB_DIR_BIN, _BB_SUID_NEVER, false)) -USE_FBSET(APPLET(fbset, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_FBSPLASH(APPLET(fbsplash, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, _BB_DIR_BIN, _BB_SUID_NEVER, fdflush)) -USE_FDFORMAT(APPLET(fdformat, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_FDISK(APPLET(fdisk, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_FEATURE_GREP_FGREP_ALIAS(APPLET_ODDNAME(fgrep, grep, _BB_DIR_BIN, _BB_SUID_NEVER, fgrep)) -USE_FIND(APPLET_NOEXEC(find, find, _BB_DIR_USR_BIN, _BB_SUID_NEVER, find)) -USE_FINDFS(APPLET(findfs, _BB_DIR_SBIN, _BB_SUID_MAYBE)) -//USE_FLASH_ERASEALL(APPLET_ODDNAME(flash_eraseall, flash_eraseall, _BB_DIR_USR_SBIN, _BB_SUID_NEVER, flash_eraseall)) -USE_FLASH_ERASEALL(APPLET(flash_eraseall, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_FOLD(APPLET(fold, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_FREE(APPLET(free, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_FREERAMDISK(APPLET(freeramdisk, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_FSCK(APPLET(fsck, _BB_DIR_SBIN, _BB_SUID_NEVER)) -//USE_E2FSCK(APPLET_ODDNAME(fsck.ext2, e2fsck, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_ext2)) -//USE_E2FSCK(APPLET_ODDNAME(fsck.ext3, e2fsck, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_ext3)) -USE_FSCK_MINIX(APPLET_ODDNAME(fsck.minix, fsck_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_minix)) -USE_FTPD(APPLET(ftpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_FTPGET(APPLET_ODDNAME(ftpget, ftpgetput, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ftpget)) -USE_FTPPUT(APPLET_ODDNAME(ftpput, ftpgetput, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ftpput)) -USE_FUSER(APPLET(fuser, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_GETENFORCE(APPLET(getenforce, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_GETOPT(APPLET(getopt, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_GETSEBOOL(APPLET(getsebool, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_GETTY(APPLET(getty, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_GREP(APPLET(grep, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_GUNZIP(APPLET(gunzip, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_GZIP(APPLET(gzip, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_HALT(APPLET(halt, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_HD(APPLET_NOEXEC(hd, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hd)) -USE_HDPARM(APPLET(hdparm, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_HEAD(APPLET(head, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hexdump)) -USE_HOSTID(APPLET_NOFORK(hostid, hostid, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hostid)) -USE_HOSTNAME(APPLET(hostname, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_HTTPD(APPLET(httpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_HUSH(APPLET(hush, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_HWCLOCK(APPLET(hwclock, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_ID(APPLET(id, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_IFCONFIG(APPLET(ifconfig, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_IFUPDOWN(APPLET_ODDNAME(ifdown, ifupdown, _BB_DIR_SBIN, _BB_SUID_NEVER, ifdown)) -USE_IFENSLAVE(APPLET(ifenslave, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_IFUPDOWN(APPLET_ODDNAME(ifup, ifupdown, _BB_DIR_SBIN, _BB_SUID_NEVER, ifup)) -USE_INETD(APPLET(inetd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_INOTIFYD(APPLET(inotifyd, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_INSMOD(APPLET(insmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) -USE_INSTALL(APPLET(install, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_IONICE(APPLET(ionice, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_TEST(APPLET_NOFORK([, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test)) +IF_TEST(APPLET_NOFORK([[, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test)) +IF_ACPID(APPLET(acpid, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_ADDGROUP(APPLET(addgroup, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_ADDUSER(APPLET(adduser, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_ADJTIMEX(APPLET(adjtimex, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_AR(APPLET(ar, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_ARP(APPLET(arp, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_ARPING(APPLET(arping, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_ASH(APPLET(ash, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_AWK(APPLET_NOEXEC(awk, awk, _BB_DIR_USR_BIN, _BB_SUID_NEVER, awk)) +IF_BASENAME(APPLET_NOFORK(basename, basename, _BB_DIR_USR_BIN, _BB_SUID_NEVER, basename)) +IF_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_NEVER)) +//IF_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_BLKID(APPLET(blkid, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_BRCTL(APPLET(brctl, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_BUNZIP2(APPLET(bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER, bzcat)) +IF_BZIP2(APPLET(bzip2, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CAL(APPLET(cal, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CAT(APPLET_NOFORK(cat, cat, _BB_DIR_BIN, _BB_SUID_NEVER, cat)) +IF_CATV(APPLET(catv, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_CHAT(APPLET(chat, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CHATTR(APPLET(chattr, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_CHCON(APPLET(chcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CHGRP(APPLET_NOEXEC(chgrp, chgrp, _BB_DIR_BIN, _BB_SUID_NEVER, chgrp)) +IF_CHMOD(APPLET_NOEXEC(chmod, chmod, _BB_DIR_BIN, _BB_SUID_NEVER, chmod)) +IF_CHOWN(APPLET_NOEXEC(chown, chown, _BB_DIR_BIN, _BB_SUID_NEVER, chown)) +IF_CHPASSWD(APPLET(chpasswd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_CHPST(APPLET(chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CHROOT(APPLET(chroot, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_CHRT(APPLET(chrt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CHVT(APPLET(chvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CKSUM(APPLET(cksum, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CLEAR(APPLET(clear, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CMP(APPLET(cmp, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_COMM(APPLET(comm, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CP(APPLET_NOEXEC(cp, cp, _BB_DIR_BIN, _BB_SUID_NEVER, cp)) +IF_CPIO(APPLET(cpio, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_CROND(APPLET(crond, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_CRONTAB(APPLET(crontab, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) +IF_CRYPTPW(APPLET(cryptpw, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_CTTYHACK(APPLET(cttyhack, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_CUT(APPLET_NOEXEC(cut, cut, _BB_DIR_USR_BIN, _BB_SUID_NEVER, cut)) +IF_DATE(APPLET(date, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_DC(APPLET(dc, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_DD(APPLET_NOEXEC(dd, dd, _BB_DIR_BIN, _BB_SUID_NEVER, dd)) +IF_DEALLOCVT(APPLET(deallocvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_DELGROUP(APPLET_ODDNAME(delgroup, deluser, _BB_DIR_BIN, _BB_SUID_NEVER, delgroup)) +IF_DELUSER(APPLET(deluser, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_DEPMOD(APPLET(depmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) +IF_DEVFSD(APPLET(devfsd, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_DEVMEM(APPLET(devmem, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_DF(APPLET(df, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_APP_DHCPRELAY(APPLET(dhcprelay, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_DIFF(APPLET(diff, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_DIRNAME(APPLET_NOFORK(dirname, dirname, _BB_DIR_USR_BIN, _BB_SUID_NEVER, dirname)) +IF_DMESG(APPLET(dmesg, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_DNSD(APPLET(dnsd, _BB_DIR_USR_SBIN, _BB_SUID_ALWAYS)) +IF_DOS2UNIX(APPLET(dos2unix, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_DPKG(APPLET(dpkg, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, _BB_DIR_USR_BIN, _BB_SUID_NEVER, dpkg_deb)) +IF_DU(APPLET(du, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_DUMPKMAP(APPLET(dumpkmap, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_APP_DUMPLEASES(APPLET(dumpleases, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +//IF_E2FSCK(APPLET(e2fsck, _BB_DIR_SBIN, _BB_SUID_NEVER)) +//IF_E2LABEL(APPLET_ODDNAME(e2label, tune2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, e2label)) +IF_ECHO(APPLET_NOFORK(echo, echo, _BB_DIR_BIN, _BB_SUID_NEVER, echo)) +IF_ED(APPLET(ed, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_FEATURE_GREP_EGREP_ALIAS(APPLET_ODDNAME(egrep, grep, _BB_DIR_BIN, _BB_SUID_NEVER, egrep)) +IF_EJECT(APPLET(eject, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_ENV(APPLET_NOEXEC(env, env, _BB_DIR_USR_BIN, _BB_SUID_NEVER, env)) +IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, envdir)) +IF_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, envuidgid)) +IF_ETHER_WAKE(APPLET_ODDNAME(ether-wake, ether_wake, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ether_wake)) +IF_EXPAND(APPLET(expand, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_EXPR(APPLET(expr, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_FAKEIDENTD(APPLET(fakeidentd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_FALSE(APPLET_NOFORK(false, false, _BB_DIR_BIN, _BB_SUID_NEVER, false)) +IF_FBSET(APPLET(fbset, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_FBSPLASH(APPLET(fbsplash, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, _BB_DIR_BIN, _BB_SUID_NEVER, fdflush)) +IF_FDFORMAT(APPLET(fdformat, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_FDISK(APPLET(fdisk, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_FEATURE_GREP_FGREP_ALIAS(APPLET_ODDNAME(fgrep, grep, _BB_DIR_BIN, _BB_SUID_NEVER, fgrep)) +IF_FIND(APPLET_NOEXEC(find, find, _BB_DIR_USR_BIN, _BB_SUID_NEVER, find)) +IF_FINDFS(APPLET(findfs, _BB_DIR_SBIN, _BB_SUID_MAYBE)) +//IF_FLASH_ERASEALL(APPLET_ODDNAME(flash_eraseall, flash_eraseall, _BB_DIR_USR_SBIN, _BB_SUID_NEVER, flash_eraseall)) +IF_FLASH_ERASEALL(APPLET(flash_eraseall, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_FOLD(APPLET(fold, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_FREE(APPLET(free, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_FREERAMDISK(APPLET(freeramdisk, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_FSCK(APPLET(fsck, _BB_DIR_SBIN, _BB_SUID_NEVER)) +//IF_E2FSCK(APPLET_ODDNAME(fsck.ext2, e2fsck, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_ext2)) +//IF_E2FSCK(APPLET_ODDNAME(fsck.ext3, e2fsck, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_ext3)) +IF_FSCK_MINIX(APPLET_ODDNAME(fsck.minix, fsck_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, fsck_minix)) +IF_FTPD(APPLET(ftpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_FTPGET(APPLET_ODDNAME(ftpget, ftpgetput, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ftpget)) +IF_FTPPUT(APPLET_ODDNAME(ftpput, ftpgetput, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ftpput)) +IF_FUSER(APPLET(fuser, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_GETENFORCE(APPLET(getenforce, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_GETOPT(APPLET(getopt, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_GETSEBOOL(APPLET(getsebool, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_GETTY(APPLET(getty, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_GREP(APPLET(grep, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_GUNZIP(APPLET(gunzip, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_GZIP(APPLET(gzip, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_HALT(APPLET(halt, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_HD(APPLET_NOEXEC(hd, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hd)) +IF_HDPARM(APPLET(hdparm, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_HEAD(APPLET(head, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hexdump)) +IF_HOSTID(APPLET_NOFORK(hostid, hostid, _BB_DIR_USR_BIN, _BB_SUID_NEVER, hostid)) +IF_HOSTNAME(APPLET(hostname, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_HTTPD(APPLET(httpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_HUSH(APPLET(hush, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_HWCLOCK(APPLET(hwclock, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_ID(APPLET(id, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_IFCONFIG(APPLET(ifconfig, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_IFUPDOWN(APPLET_ODDNAME(ifdown, ifupdown, _BB_DIR_SBIN, _BB_SUID_NEVER, ifdown)) +IF_IFENSLAVE(APPLET(ifenslave, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_IFUPDOWN(APPLET_ODDNAME(ifup, ifupdown, _BB_DIR_SBIN, _BB_SUID_NEVER, ifup)) +IF_INETD(APPLET(inetd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_INIT(APPLET(init, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_INOTIFYD(APPLET(inotifyd, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_INSMOD(APPLET(insmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) +IF_INSTALL(APPLET(install, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_IONICE(APPLET(ionice, _BB_DIR_BIN, _BB_SUID_NEVER)) #if ENABLE_FEATURE_IP_ADDRESS \ || ENABLE_FEATURE_IP_ROUTE \ || ENABLE_FEATURE_IP_LINK \ || ENABLE_FEATURE_IP_TUNNEL \ || ENABLE_FEATURE_IP_RULE -USE_IP(APPLET(ip, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_IP(APPLET(ip, _BB_DIR_BIN, _BB_SUID_NEVER)) #endif -USE_IPADDR(APPLET(ipaddr, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_IPCALC(APPLET(ipcalc, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_IPCRM(APPLET(ipcrm, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) -USE_IPCS(APPLET(ipcs, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) -USE_IPLINK(APPLET(iplink, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_IPROUTE(APPLET(iproute, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_IPRULE(APPLET(iprule, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_KBD_MODE(APPLET(kbd_mode, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall)) -USE_KILLALL5(APPLET_ODDNAME(killall5, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall5)) -USE_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_LENGTH(APPLET_NOFORK(length, length, _BB_DIR_USR_BIN, _BB_SUID_NEVER, length)) -USE_LESS(APPLET(less, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SETARCH(APPLET_ODDNAME(linux32, setarch, _BB_DIR_BIN, _BB_SUID_NEVER, linux32)) -USE_SETARCH(APPLET_ODDNAME(linux64, setarch, _BB_DIR_BIN, _BB_SUID_NEVER, linux64)) -USE_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, _BB_DIR_ROOT, _BB_SUID_NEVER, linuxrc)) -USE_LN(APPLET_NOEXEC(ln, ln, _BB_DIR_BIN, _BB_SUID_NEVER, ln)) -USE_LOAD_POLICY(APPLET(load_policy, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_LOADFONT(APPLET(loadfont, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_LOADKMAP(APPLET(loadkmap, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_LOGGER(APPLET(logger, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_LOGIN(APPLET(login, _BB_DIR_BIN, _BB_SUID_ALWAYS)) -USE_LOGNAME(APPLET_NOFORK(logname, logname, _BB_DIR_USR_BIN, _BB_SUID_NEVER, logname)) -USE_LOGREAD(APPLET(logread, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_LOSETUP(APPLET(losetup, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_LPD(APPLET(lpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_LPQ(APPLET_ODDNAME(lpq, lpqr, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lpq)) -USE_LPR(APPLET_ODDNAME(lpr, lpqr, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lpr)) -USE_LS(APPLET_NOEXEC(ls, ls, _BB_DIR_BIN, _BB_SUID_NEVER, ls)) -USE_LSATTR(APPLET(lsattr, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) -USE_UNLZMA(APPLET_ODDNAME(lzmacat, unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzmacat)) -USE_MAKEDEVS(APPLET(makedevs, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MAKEMIME(APPLET(makemime, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MATCHPATHCON(APPLET(matchpathcon, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_MD5SUM(APPLET_ODDNAME(md5sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, md5sum)) -USE_MDEV(APPLET(mdev, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MESG(APPLET(mesg, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_MICROCOM(APPLET(microcom, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_MKDIR(APPLET_NOFORK(mkdir, mkdir, _BB_DIR_BIN, _BB_SUID_NEVER, mkdir)) -USE_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_vfat)) -//USE_MKE2FS(APPLET(mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MKFIFO(APPLET(mkfifo, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -//USE_MKE2FS(APPLET_ODDNAME(mkfs.ext2, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext2)) -//USE_MKE2FS(APPLET_ODDNAME(mkfs.ext3, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext3)) -USE_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_minix)) -USE_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_vfat)) -USE_MKNOD(APPLET(mknod, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, _BB_DIR_USR_BIN, _BB_SUID_NEVER, mkpasswd)) -USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MODPROBE_SMALL(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_MOUNT(APPLET(mount, _BB_DIR_BIN, USE_DESKTOP(_BB_SUID_MAYBE) SKIP_DESKTOP(_BB_SUID_NEVER))) -USE_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_MSH(APPLET(msh, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_MT(APPLET(mt, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_MV(APPLET(mv, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_NAMEIF(APPLET(nameif, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_NC(APPLET(nc, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_NETSTAT(APPLET(netstat, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_NICE(APPLET(nice, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_NMETER(APPLET(nmeter, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_NOHUP(APPLET(nohup, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_NSLOOKUP(APPLET(nslookup, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_OD(APPLET(od, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_OPENVT(APPLET(openvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -//USE_PARSE(APPLET(parse, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_PASSWD(APPLET(passwd, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) -USE_PATCH(APPLET(patch, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_PGREP(APPLET(pgrep, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_PIDOF(APPLET(pidof, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_PING(APPLET(ping, _BB_DIR_BIN, _BB_SUID_MAYBE)) -USE_PING6(APPLET(ping6, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_PIPE_PROGRESS(APPLET(pipe_progress, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_PIVOT_ROOT(APPLET(pivot_root, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_PKILL(APPLET_ODDNAME(pkill, pgrep, _BB_DIR_USR_BIN, _BB_SUID_NEVER, pkill)) -USE_POPMAILDIR(APPLET(popmaildir, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_HALT(APPLET_ODDNAME(poweroff, halt, _BB_DIR_SBIN, _BB_SUID_NEVER, poweroff)) -USE_PRINTENV(APPLET(printenv, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_PRINTF(APPLET_NOFORK(printf, printf, _BB_DIR_USR_BIN, _BB_SUID_NEVER, printf)) -USE_PS(APPLET(ps, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_PSCAN(APPLET(pscan, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_PWD(APPLET_NOFORK(pwd, pwd, _BB_DIR_BIN, _BB_SUID_NEVER, pwd)) -USE_RAIDAUTORUN(APPLET(raidautorun, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_RDATE(APPLET(rdate, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_RDEV(APPLET(rdev, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_READAHEAD(APPLET(readahead, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_READLINK(APPLET(readlink, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_READPROFILE(APPLET(readprofile, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_REALPATH(APPLET(realpath, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_HALT(APPLET_ODDNAME(reboot, halt, _BB_DIR_SBIN, _BB_SUID_NEVER, reboot)) -USE_REFORMIME(APPLET(reformime, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_RENICE(APPLET(renice, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RESET(APPLET(reset, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RESIZE(APPLET(resize, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RESTORECON(APPLET_ODDNAME(restorecon, setfiles, _BB_DIR_SBIN, _BB_SUID_NEVER, restorecon)) -USE_RM(APPLET_NOFORK(rm, rm, _BB_DIR_BIN, _BB_SUID_NEVER, rm)) -USE_RMDIR(APPLET_NOFORK(rmdir, rmdir, _BB_DIR_BIN, _BB_SUID_NEVER, rmdir)) -USE_RMMOD(APPLET(rmmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) -USE_ROUTE(APPLET(route, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_RPM2CPIO(APPLET(rpm2cpio, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RTCWAKE(APPLET(rtcwake, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)) -USE_RUNCON(APPLET(runcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RUNLEVEL(APPLET(runlevel, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_RUNSV(APPLET(runsv, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RUNSVDIR(APPLET(runsvdir, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_RX(APPLET(rx, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SCRIPT(APPLET(script, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SED(APPLET(sed, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_SELINUXENABLED(APPLET(selinuxenabled, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SENDMAIL(APPLET(sendmail, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SEQ(APPLET_NOFORK(seq, seq, _BB_DIR_USR_BIN, _BB_SUID_NEVER, seq)) -USE_SESTATUS(APPLET(sestatus, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SETARCH(APPLET(setarch, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_SETCONSOLE(APPLET(setconsole, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_SETENFORCE(APPLET(setenforce, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SETFILES(APPLET(setfiles, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_SETFONT(APPLET(setfont, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SETKEYCODES(APPLET(setkeycodes, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SETLOGCONS(APPLET(setlogcons, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SETSEBOOL(APPLET(setsebool, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SETSID(APPLET(setsid, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, setuidgid)) -USE_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, _BB_DIR_BIN, _BB_SUID_NEVER, sh)) -USE_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, _BB_DIR_BIN, _BB_SUID_NEVER, sh)) -USE_FEATURE_SH_IS_MSH(APPLET_ODDNAME(sh, msh, _BB_DIR_BIN, _BB_SUID_NEVER, sh)) -USE_SHA1SUM(APPLET_ODDNAME(sha1sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha1sum)) -USE_SHA256SUM(APPLET_ODDNAME(sha256sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha256sum)) -USE_SHA512SUM(APPLET_ODDNAME(sha512sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha512sum)) -USE_SHOWKEY(APPLET(showkey, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SLATTACH(APPLET(slattach, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_SLEEP(APPLET_NOFORK(sleep, sleep, _BB_DIR_BIN, _BB_SUID_NEVER, sleep)) -USE_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, softlimit)) -USE_SORT(APPLET_NOEXEC(sort, sort, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sort)) -USE_SPLIT(APPLET(split, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, _BB_DIR_SBIN, _BB_SUID_NEVER, start_stop_daemon)) -USE_STAT(APPLET(stat, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_STRINGS(APPLET(strings, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_STTY(APPLET(stty, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_SU(APPLET(su, _BB_DIR_BIN, _BB_SUID_ALWAYS)) -USE_SULOGIN(APPLET(sulogin, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_SUM(APPLET(sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SV(APPLET(sv, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_SVLOGD(APPLET(svlogd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_SWAPONOFF(APPLET_ODDNAME(swapoff, swap_on_off, _BB_DIR_SBIN, _BB_SUID_NEVER,swapoff)) -USE_SWAPONOFF(APPLET_ODDNAME(swapon, swap_on_off, _BB_DIR_SBIN, _BB_SUID_NEVER, swapon)) -USE_SWITCH_ROOT(APPLET(switch_root, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_SYNC(APPLET_NOFORK(sync, sync, _BB_DIR_BIN, _BB_SUID_NEVER, sync)) -USE_BB_SYSCTL(APPLET(sysctl, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_SYSLOGD(APPLET(syslogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_TAC(APPLET_NOEXEC(tac, tac, _BB_DIR_USR_BIN, _BB_SUID_NEVER, tac)) -USE_TAIL(APPLET(tail, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TAR(APPLET(tar, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_TASKSET(APPLET(taskset, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -/* USE_TC(APPLET(tc, _BB_DIR_SBIN, _BB_SUID_NEVER)) */ -USE_TCPSVD(APPLET_ODDNAME(tcpsvd, tcpudpsvd, _BB_DIR_USR_BIN, _BB_SUID_NEVER, tcpsvd)) -USE_TEE(APPLET(tee, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TELNET(APPLET(telnet, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TELNETD(APPLET(telnetd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_TEST(APPLET_NOFORK(test, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test)) +IF_IPADDR(APPLET(ipaddr, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_IPCALC(APPLET(ipcalc, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_IPCRM(APPLET(ipcrm, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) +IF_IPCS(APPLET(ipcs, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) +IF_IPLINK(APPLET(iplink, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_IPROUTE(APPLET(iproute, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_IPRULE(APPLET(iprule, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_IPTUNNEL(APPLET(iptunnel, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_KBD_MODE(APPLET(kbd_mode, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall)) +IF_KILLALL5(APPLET_ODDNAME(killall5, kill, _BB_DIR_USR_BIN, _BB_SUID_NEVER, killall5)) +IF_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_LENGTH(APPLET_NOFORK(length, length, _BB_DIR_USR_BIN, _BB_SUID_NEVER, length)) +IF_LESS(APPLET(less, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SETARCH(APPLET_ODDNAME(linux32, setarch, _BB_DIR_BIN, _BB_SUID_NEVER, linux32)) +IF_SETARCH(APPLET_ODDNAME(linux64, setarch, _BB_DIR_BIN, _BB_SUID_NEVER, linux64)) +IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, _BB_DIR_ROOT, _BB_SUID_NEVER, linuxrc)) +IF_LN(APPLET_NOEXEC(ln, ln, _BB_DIR_BIN, _BB_SUID_NEVER, ln)) +IF_LOAD_POLICY(APPLET(load_policy, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_LOADFONT(APPLET(loadfont, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_LOADKMAP(APPLET(loadkmap, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_LOGGER(APPLET(logger, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_LOGIN(APPLET(login, _BB_DIR_BIN, _BB_SUID_ALWAYS)) +IF_LOGNAME(APPLET_NOFORK(logname, logname, _BB_DIR_USR_BIN, _BB_SUID_NEVER, logname)) +IF_LOGREAD(APPLET(logread, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_LOSETUP(APPLET(losetup, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_LPD(APPLET(lpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_LPQ(APPLET_ODDNAME(lpq, lpqr, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lpq)) +IF_LPR(APPLET_ODDNAME(lpr, lpqr, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lpr)) +IF_LS(APPLET_NOEXEC(ls, ls, _BB_DIR_BIN, _BB_SUID_NEVER, ls)) +IF_LSATTR(APPLET(lsattr, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) +IF_UNLZMA(APPLET_ODDNAME(lzmacat, unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER, lzmacat)) +IF_MAKEDEVS(APPLET(makedevs, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MAKEMIME(APPLET(makemime, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_MAN(APPLET(man, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MATCHPATHCON(APPLET(matchpathcon, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_MD5SUM(APPLET_ODDNAME(md5sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, md5sum)) +IF_MDEV(APPLET(mdev, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MESG(APPLET(mesg, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_MICROCOM(APPLET(microcom, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, _BB_DIR_BIN, _BB_SUID_NEVER, mkdir)) +IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_vfat)) +//IF_MKE2FS(APPLET(mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MKFIFO(APPLET(mkfifo, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +//IF_MKE2FS(APPLET_ODDNAME(mkfs.ext2, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext2)) +//IF_MKE2FS(APPLET_ODDNAME(mkfs.ext3, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext3)) +IF_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_minix)) +IF_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_vfat)) +IF_MKNOD(APPLET(mknod, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, _BB_DIR_USR_BIN, _BB_SUID_NEVER, mkpasswd)) +IF_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MODPROBE_SMALL(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_MOUNT(APPLET(mount, _BB_DIR_BIN, IF_DESKTOP(_BB_SUID_MAYBE) IF_NOT_DESKTOP(_BB_SUID_NEVER))) +IF_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_MSH(APPLET(msh, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_MT(APPLET(mt, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_MV(APPLET(mv, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_NAMEIF(APPLET(nameif, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_NC(APPLET(nc, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_NETSTAT(APPLET(netstat, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_NICE(APPLET(nice, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_NMETER(APPLET(nmeter, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_NOHUP(APPLET(nohup, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_NSLOOKUP(APPLET(nslookup, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_OD(APPLET(od, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_OPENVT(APPLET(openvt, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +//IF_PARSE(APPLET(parse, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_PASSWD(APPLET(passwd, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) +IF_PATCH(APPLET(patch, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_PGREP(APPLET(pgrep, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_PIDOF(APPLET(pidof, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_PING(APPLET(ping, _BB_DIR_BIN, _BB_SUID_MAYBE)) +IF_PING6(APPLET(ping6, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_PIPE_PROGRESS(APPLET(pipe_progress, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_PIVOT_ROOT(APPLET(pivot_root, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_PKILL(APPLET_ODDNAME(pkill, pgrep, _BB_DIR_USR_BIN, _BB_SUID_NEVER, pkill)) +IF_POPMAILDIR(APPLET(popmaildir, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_HALT(APPLET_ODDNAME(poweroff, halt, _BB_DIR_SBIN, _BB_SUID_NEVER, poweroff)) +IF_PRINTENV(APPLET(printenv, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_PRINTF(APPLET_NOFORK(printf, printf, _BB_DIR_USR_BIN, _BB_SUID_NEVER, printf)) +IF_PS(APPLET(ps, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_PSCAN(APPLET(pscan, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_PWD(APPLET_NOFORK(pwd, pwd, _BB_DIR_BIN, _BB_SUID_NEVER, pwd)) +IF_RAIDAUTORUN(APPLET(raidautorun, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_RDATE(APPLET(rdate, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_RDEV(APPLET(rdev, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_READAHEAD(APPLET(readahead, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_READLINK(APPLET(readlink, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_READPROFILE(APPLET(readprofile, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_REALPATH(APPLET(realpath, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_HALT(APPLET_ODDNAME(reboot, halt, _BB_DIR_SBIN, _BB_SUID_NEVER, reboot)) +IF_REFORMIME(APPLET(reformime, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_RENICE(APPLET(renice, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RESET(APPLET(reset, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RESIZE(APPLET(resize, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RESTORECON(APPLET_ODDNAME(restorecon, setfiles, _BB_DIR_SBIN, _BB_SUID_NEVER, restorecon)) +IF_RM(APPLET_NOFORK(rm, rm, _BB_DIR_BIN, _BB_SUID_NEVER, rm)) +IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, _BB_DIR_BIN, _BB_SUID_NEVER, rmdir)) +IF_RMMOD(APPLET(rmmod, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER, modprobe)) +IF_ROUTE(APPLET(route, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_RPM(APPLET(rpm, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_RPM2CPIO(APPLET(rpm2cpio, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RTCWAKE(APPLET(rtcwake, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, _BB_DIR_BIN, _BB_SUID_NEVER, run_parts)) +IF_RUNCON(APPLET(runcon, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RUNLEVEL(APPLET(runlevel, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_RUNSV(APPLET(runsv, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RUNSVDIR(APPLET(runsvdir, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_RX(APPLET(rx, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SCRIPT(APPLET(script, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SED(APPLET(sed, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_SELINUXENABLED(APPLET(selinuxenabled, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SENDMAIL(APPLET(sendmail, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SEQ(APPLET_NOFORK(seq, seq, _BB_DIR_USR_BIN, _BB_SUID_NEVER, seq)) +IF_SESTATUS(APPLET(sestatus, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SETARCH(APPLET(setarch, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_SETCONSOLE(APPLET(setconsole, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_SETENFORCE(APPLET(setenforce, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SETFILES(APPLET(setfiles, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_SETFONT(APPLET(setfont, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SETKEYCODES(APPLET(setkeycodes, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SETLOGCONS(APPLET(setlogcons, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SETSEBOOL(APPLET(setsebool, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SETSID(APPLET(setsid, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, setuidgid)) +IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, _BB_DIR_BIN, _BB_SUID_NEVER, sh)) +IF_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, _BB_DIR_BIN, _BB_SUID_NEVER, sh)) +IF_FEATURE_SH_IS_MSH(APPLET_ODDNAME(sh, msh, _BB_DIR_BIN, _BB_SUID_NEVER, sh)) +IF_SHA1SUM(APPLET_ODDNAME(sha1sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha1sum)) +IF_SHA256SUM(APPLET_ODDNAME(sha256sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha256sum)) +IF_SHA512SUM(APPLET_ODDNAME(sha512sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sha512sum)) +IF_SHOWKEY(APPLET(showkey, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SLATTACH(APPLET(slattach, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_SLEEP(APPLET_NOFORK(sleep, sleep, _BB_DIR_BIN, _BB_SUID_NEVER, sleep)) +IF_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, _BB_DIR_USR_BIN, _BB_SUID_NEVER, softlimit)) +IF_SORT(APPLET_NOEXEC(sort, sort, _BB_DIR_USR_BIN, _BB_SUID_NEVER, sort)) +IF_SPLIT(APPLET(split, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, _BB_DIR_SBIN, _BB_SUID_NEVER, start_stop_daemon)) +IF_STAT(APPLET(stat, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_STRINGS(APPLET(strings, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_STTY(APPLET(stty, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_SU(APPLET(su, _BB_DIR_BIN, _BB_SUID_ALWAYS)) +IF_SULOGIN(APPLET(sulogin, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_SUM(APPLET(sum, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SV(APPLET(sv, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_SVLOGD(APPLET(svlogd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_SWAPONOFF(APPLET_ODDNAME(swapoff, swap_on_off, _BB_DIR_SBIN, _BB_SUID_NEVER,swapoff)) +IF_SWAPONOFF(APPLET_ODDNAME(swapon, swap_on_off, _BB_DIR_SBIN, _BB_SUID_NEVER, swapon)) +IF_SWITCH_ROOT(APPLET(switch_root, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_SYNC(APPLET_NOFORK(sync, sync, _BB_DIR_BIN, _BB_SUID_NEVER, sync)) +IF_BB_SYSCTL(APPLET(sysctl, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_SYSLOGD(APPLET(syslogd, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_TAC(APPLET_NOEXEC(tac, tac, _BB_DIR_USR_BIN, _BB_SUID_NEVER, tac)) +IF_TAIL(APPLET(tail, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TAR(APPLET(tar, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_TASKSET(APPLET(taskset, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +/* IF_TC(APPLET(tc, _BB_DIR_SBIN, _BB_SUID_NEVER)) */ +IF_TCPSVD(APPLET_ODDNAME(tcpsvd, tcpudpsvd, _BB_DIR_USR_BIN, _BB_SUID_NEVER, tcpsvd)) +IF_TEE(APPLET(tee, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TELNET(APPLET(telnet, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TELNETD(APPLET(telnetd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_TEST(APPLET_NOFORK(test, test, _BB_DIR_USR_BIN, _BB_SUID_NEVER, test)) #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT -USE_TFTP(APPLET(tftp, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TFTPD(APPLET(tftpd, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TFTP(APPLET(tftp, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TFTPD(APPLET(tftpd, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) #endif -USE_TIME(APPLET(time, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TIMEOUT(APPLET(timeout, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TOP(APPLET(top, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TOUCH(APPLET_NOFORK(touch, touch, _BB_DIR_BIN, _BB_SUID_NEVER, touch)) -USE_TR(APPLET(tr, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TRACEROUTE(APPLET(traceroute, _BB_DIR_USR_BIN, _BB_SUID_MAYBE)) -USE_TRUE(APPLET_NOFORK(true, true, _BB_DIR_BIN, _BB_SUID_NEVER, true)) -USE_TTY(APPLET(tty, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TTYSIZE(APPLET(ttysize, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_TUNCTL(APPLET(tunctl, _BB_DIR_SBIN, _BB_SUID_NEVER)) -//USE_TUNE2FS(APPLET(tune2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_APP_UDHCPC(APPLET(udhcpc, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_APP_UDHCPD(APPLET(udhcpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) -USE_UDPSVD(APPLET_ODDNAME(udpsvd, tcpudpsvd, _BB_DIR_USR_BIN, _BB_SUID_NEVER, udpsvd)) -USE_UMOUNT(APPLET(umount, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_UNAME(APPLET(uname, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_UNCOMPRESS(APPLET(uncompress, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_UNEXPAND(APPLET_ODDNAME(unexpand, expand, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unexpand)) -USE_UNIQ(APPLET(uniq, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_UNIX2DOS(APPLET_ODDNAME(unix2dos, dos2unix, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unix2dos)) -USE_UNLZMA(APPLET(unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_UNZIP(APPLET(unzip, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_UPTIME(APPLET(uptime, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_USLEEP(APPLET_NOFORK(usleep, usleep, _BB_DIR_BIN, _BB_SUID_NEVER, usleep)) -USE_UUDECODE(APPLET(uudecode, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_UUENCODE(APPLET(uuencode, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_VCONFIG(APPLET(vconfig, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_VI(APPLET(vi, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_VLOCK(APPLET(vlock, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) -USE_WATCH(APPLET(watch, _BB_DIR_BIN, _BB_SUID_NEVER)) -USE_WATCHDOG(APPLET(watchdog, _BB_DIR_SBIN, _BB_SUID_NEVER)) -USE_WC(APPLET(wc, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_WGET(APPLET(wget, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_WHICH(APPLET(which, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_WHO(APPLET(who, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) -USE_WHOAMI(APPLET_NOFORK(whoami, whoami, _BB_DIR_USR_BIN, _BB_SUID_NEVER, whoami)) -USE_XARGS(APPLET_NOEXEC(xargs, xargs, _BB_DIR_USR_BIN, _BB_SUID_NEVER, xargs)) -USE_YES(APPLET_NOFORK(yes, yes, _BB_DIR_USR_BIN, _BB_SUID_NEVER, yes)) -USE_GUNZIP(APPLET_ODDNAME(zcat, gunzip, _BB_DIR_BIN, _BB_SUID_NEVER, zcat)) -USE_ZCIP(APPLET(zcip, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_TIME(APPLET(time, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TIMEOUT(APPLET(timeout, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TOP(APPLET(top, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TOUCH(APPLET_NOFORK(touch, touch, _BB_DIR_BIN, _BB_SUID_NEVER, touch)) +IF_TR(APPLET(tr, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TRACEROUTE(APPLET(traceroute, _BB_DIR_USR_BIN, _BB_SUID_MAYBE)) +IF_TRUE(APPLET_NOFORK(true, true, _BB_DIR_BIN, _BB_SUID_NEVER, true)) +IF_TTY(APPLET(tty, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TTYSIZE(APPLET(ttysize, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_TUNCTL(APPLET(tunctl, _BB_DIR_SBIN, _BB_SUID_NEVER)) +//IF_TUNE2FS(APPLET(tune2fs, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_APP_UDHCPC(APPLET(udhcpc, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_APP_UDHCPD(APPLET(udhcpd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) +IF_UDPSVD(APPLET_ODDNAME(udpsvd, tcpudpsvd, _BB_DIR_USR_BIN, _BB_SUID_NEVER, udpsvd)) +IF_UMOUNT(APPLET(umount, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_UNAME(APPLET(uname, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_UNCOMPRESS(APPLET(uncompress, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unexpand)) +IF_UNIQ(APPLET(uniq, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_UNIX2DOS(APPLET_ODDNAME(unix2dos, dos2unix, _BB_DIR_USR_BIN, _BB_SUID_NEVER, unix2dos)) +IF_UNLZMA(APPLET(unlzma, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_UNZIP(APPLET(unzip, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_UPTIME(APPLET(uptime, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_USLEEP(APPLET_NOFORK(usleep, usleep, _BB_DIR_BIN, _BB_SUID_NEVER, usleep)) +IF_UUDECODE(APPLET(uudecode, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_UUENCODE(APPLET(uuencode, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_VCONFIG(APPLET(vconfig, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_VI(APPLET(vi, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_VLOCK(APPLET(vlock, _BB_DIR_USR_BIN, _BB_SUID_ALWAYS)) +IF_WATCH(APPLET(watch, _BB_DIR_BIN, _BB_SUID_NEVER)) +IF_WATCHDOG(APPLET(watchdog, _BB_DIR_SBIN, _BB_SUID_NEVER)) +IF_WC(APPLET(wc, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_WGET(APPLET(wget, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_WHICH(APPLET(which, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_WHO(APPLET(who, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) +IF_WHOAMI(APPLET_NOFORK(whoami, whoami, _BB_DIR_USR_BIN, _BB_SUID_NEVER, whoami)) +IF_XARGS(APPLET_NOEXEC(xargs, xargs, _BB_DIR_USR_BIN, _BB_SUID_NEVER, xargs)) +IF_YES(APPLET_NOFORK(yes, yes, _BB_DIR_USR_BIN, _BB_SUID_NEVER, yes)) +IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, _BB_DIR_BIN, _BB_SUID_NEVER, zcat)) +IF_ZCIP(APPLET(zcip, _BB_DIR_SBIN, _BB_SUID_NEVER)) #if !defined(PROTOTYPES) && !defined(NAME_MAIN_CNAME) && !defined(MAKE_USAGE) }; Index: selinux/setfiles.c =================================================================== --- selinux/setfiles.c (revision 26172) +++ selinux/setfiles.c (revision 26173) @@ -544,9 +544,9 @@ &exclude_dir, &input_filename, &out_filename, &verbose); } else { /* setfiles */ flags = getopt32(argv, "de:f:ilnpqr:svo:FW" - USE_FEATURE_SETFILES_CHECK_OPTION("c:"), + IF_FEATURE_SETFILES_CHECK_OPTION("c:"), &exclude_dir, &input_filename, &rootpath, &out_filename, - USE_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) + IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) &verbose); } Index: testsuite/all_sourcecode.tests =================================================================== --- testsuite/all_sourcecode.tests (revision 26172) +++ testsuite/all_sourcecode.tests (revision 26173) @@ -33,7 +33,7 @@ # verify the applet order is correct in applets.h, otherwise # applets won't be called properly. # -sed -n -e '/^USE_[A-Z]*(APPLET/{s:,.*::;s:.*(::;s:"::g;p}' \ +sed -n -e '/^IF_[A-Z]*(APPLET/{s:,.*::;s:.*(::;s:"::g;p}' \ $srcdir/../include/applets.h > applet.order.current LC_ALL=C sort applet.order.current > applet.order.correct testing "Applet order" "diff -u applet.order.current applet.order.correct" "" "" "" Index: loginutils/sulogin.c =================================================================== --- loginutils/sulogin.c (revision 26172) +++ loginutils/sulogin.c (revision 26173) @@ -99,7 +99,7 @@ bb_info_msg("System Maintenance Mode"); - USE_SELINUX(renew_current_security_context()); + IF_SELINUX(renew_current_security_context()); shell = getenv("SUSHELL"); if (!shell) Index: loginutils/su.c =================================================================== --- loginutils/su.c (revision 26172) +++ loginutils/su.c (revision 26173) @@ -43,7 +43,7 @@ the user, especially if someone su's from a su-shell. But getlogin can fail -- usually due to lack of utmp entry. in this case resort to getpwuid. */ - old_user = xstrdup(USE_FEATURE_UTMP(getlogin() ? : ) (pw = getpwuid(cur_uid)) ? pw->pw_name : ""); + old_user = xstrdup(IF_FEATURE_UTMP(getlogin() ? : ) (pw = getpwuid(cur_uid)) ? pw->pw_name : ""); tty = xmalloc_ttyname(2) ? : "none"; openlog(applet_name, 0, LOG_AUTH); } @@ -91,7 +91,7 @@ change_identity(pw); /* setup_environment params: shell, clear_env, change_env, pw */ setup_environment(opt_shell, flags & SU_OPT_l, !(flags & SU_OPT_mp), pw); - USE_SELINUX(set_current_security_context(NULL);) + IF_SELINUX(set_current_security_context(NULL);) /* Never returns */ run_shell(opt_shell, flags & SU_OPT_l, opt_command, (const char**)argv); Index: loginutils/login.c =================================================================== --- loginutils/login.c (revision 26172) +++ loginutils/login.c (revision 26173) @@ -285,8 +285,8 @@ char *opt_host = opt_host; /* for compiler */ char *opt_user = opt_user; /* for compiler */ char *full_tty; - USE_SELINUX(security_context_t user_sid = NULL;) - USE_FEATURE_UTMP(struct utmp utent;) + IF_SELINUX(security_context_t user_sid = NULL;) + IF_FEATURE_UTMP(struct utmp utent;) #if ENABLE_PAM int pamret; pam_handle_t *pamh; @@ -333,7 +333,7 @@ read_or_build_utent(&utent, run_by_root); if (opt & LOGIN_OPT_h) { - USE_FEATURE_UTMP(safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));) + IF_FEATURE_UTMP(safe_strncpy(utent.ut_host, opt_host, sizeof(utent.ut_host));) fromhost = xasprintf(" on '%s' from '%s'", short_tty, opt_host); } else { fromhost = xasprintf(" on '%s'", short_tty); @@ -457,7 +457,7 @@ write_utent(&utent, username); - USE_SELINUX(initselinux(username, full_tty, &user_sid)); + IF_SELINUX(initselinux(username, full_tty, &user_sid)); /* Try these, but don't complain if they fail. * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ @@ -482,7 +482,7 @@ /* well, a simple setexeccon() here would do the job as well, * but let's play the game for now */ - USE_SELINUX(set_current_security_context(user_sid);) + IF_SELINUX(set_current_security_context(user_sid);) // util-linux login also does: // /* start new session */ Index: loginutils/chpasswd.c =================================================================== --- loginutils/chpasswd.c (revision 26172) +++ loginutils/chpasswd.c (revision 26173) @@ -29,7 +29,7 @@ bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); opt_complementary = "m--e:e--m"; - USE_GETOPT_LONG(applet_long_options = chpasswd_longopts;) + IF_GETOPT_LONG(applet_long_options = chpasswd_longopts;) opt = getopt32(argv, "em"); while ((name = xmalloc_fgetline(stdin)) != NULL) { Index: runit/chpst.c =================================================================== --- runit/chpst.c (revision 26172) +++ runit/chpst.c (revision 26173) @@ -200,11 +200,11 @@ // if yes -> getopt converts strings to numbers for us opt_complementary = "-1:a+:c+:d+:f+:l+:m+:o+:p+:r+:s+:t+"; opt = getopt32(argv, "+a:c:d:f:l:m:o:p:r:s:t:u:U:e:" - USE_CHPST("/:n:vP012"), + IF_CHPST("/:n:vP012"), &limita, &limitc, &limitd, &limitf, &limitl, &limitm, &limito, &limitp, &limitr, &limits, &limitt, &set_user, &env_user, &env_dir - USE_CHPST(, &root, &nicestr)); + IF_CHPST(, &root, &nicestr)); argv += optind; if (opt & OPT_m) { // -m means -asld limita = limits = limitl = limitd = limitm; Index: findutils/find.c =================================================================== --- findutils/find.c (revision 26172) +++ findutils/find.c (revision 26173) @@ -62,8 +62,8 @@ /* This is a NOEXEC applet. Be very careful! */ -USE_FEATURE_FIND_XDEV(static dev_t *xdev_dev;) -USE_FEATURE_FIND_XDEV(static int xdev_count;) +IF_FEATURE_FIND_XDEV(static dev_t *xdev_dev;) +IF_FEATURE_FIND_XDEV(static int xdev_count;) typedef int (*action_fp)(const char *fileName, struct stat *statbuf, void *); @@ -79,23 +79,23 @@ action_##name* ap UNUSED_PARAM) ACTS(print) ACTS(name, const char *pattern; bool iname;) -USE_FEATURE_FIND_PATH( ACTS(path, const char *pattern;)) -USE_FEATURE_FIND_REGEX( ACTS(regex, regex_t compiled_pattern;)) -USE_FEATURE_FIND_PRINT0( ACTS(print0)) -USE_FEATURE_FIND_TYPE( ACTS(type, int type_mask;)) -USE_FEATURE_FIND_PERM( ACTS(perm, char perm_char; mode_t perm_mask;)) -USE_FEATURE_FIND_MTIME( ACTS(mtime, char mtime_char; unsigned mtime_days;)) -USE_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;)) -USE_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;)) -USE_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;)) -USE_FEATURE_FIND_USER( ACTS(user, uid_t uid;)) -USE_FEATURE_FIND_SIZE( ACTS(size, char size_char; off_t size;)) -USE_FEATURE_FIND_CONTEXT(ACTS(context, security_context_t context;)) -USE_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) -USE_FEATURE_FIND_PRUNE( ACTS(prune)) -USE_FEATURE_FIND_DELETE( ACTS(delete)) -USE_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) -USE_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) +IF_FEATURE_FIND_PATH( ACTS(path, const char *pattern;)) +IF_FEATURE_FIND_REGEX( ACTS(regex, regex_t compiled_pattern;)) +IF_FEATURE_FIND_PRINT0( ACTS(print0)) +IF_FEATURE_FIND_TYPE( ACTS(type, int type_mask;)) +IF_FEATURE_FIND_PERM( ACTS(perm, char perm_char; mode_t perm_mask;)) +IF_FEATURE_FIND_MTIME( ACTS(mtime, char mtime_char; unsigned mtime_days;)) +IF_FEATURE_FIND_MMIN( ACTS(mmin, char mmin_char; unsigned mmin_mins;)) +IF_FEATURE_FIND_NEWER( ACTS(newer, time_t newer_mtime;)) +IF_FEATURE_FIND_INUM( ACTS(inum, ino_t inode_num;)) +IF_FEATURE_FIND_USER( ACTS(user, uid_t uid;)) +IF_FEATURE_FIND_SIZE( ACTS(size, char size_char; off_t size;)) +IF_FEATURE_FIND_CONTEXT(ACTS(context, security_context_t context;)) +IF_FEATURE_FIND_PAREN( ACTS(paren, action ***subexpr;)) +IF_FEATURE_FIND_PRUNE( ACTS(prune)) +IF_FEATURE_FIND_DELETE( ACTS(delete)) +IF_FEATURE_FIND_EXEC( ACTS(exec, char **exec_argv; unsigned *subst_count; int exec_argc;)) +IF_FEATURE_FIND_GROUP( ACTS(group, gid_t gid;)) static action ***actions; static bool need_print = 1; @@ -376,8 +376,8 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, - void *userData SKIP_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM), - int depth SKIP_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM)) + void *userData IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM), + int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM)) { int i; #if ENABLE_FEATURE_FIND_MAXDEPTH @@ -451,73 +451,73 @@ enum { PARM_a , PARM_o , - USE_FEATURE_FIND_NOT( PARM_char_not ,) + IF_FEATURE_FIND_NOT( PARM_char_not ,) #if ENABLE_DESKTOP PARM_and , PARM_or , - USE_FEATURE_FIND_NOT( PARM_not ,) + IF_FEATURE_FIND_NOT( PARM_not ,) #endif PARM_print , - USE_FEATURE_FIND_PRINT0( PARM_print0 ,) - USE_FEATURE_FIND_DEPTH( PARM_depth ,) - USE_FEATURE_FIND_PRUNE( PARM_prune ,) - USE_FEATURE_FIND_DELETE( PARM_delete ,) - USE_FEATURE_FIND_EXEC( PARM_exec ,) - USE_FEATURE_FIND_PAREN( PARM_char_brace,) + IF_FEATURE_FIND_PRINT0( PARM_print0 ,) + IF_FEATURE_FIND_DEPTH( PARM_depth ,) + IF_FEATURE_FIND_PRUNE( PARM_prune ,) + IF_FEATURE_FIND_DELETE( PARM_delete ,) + IF_FEATURE_FIND_EXEC( PARM_exec ,) + IF_FEATURE_FIND_PAREN( PARM_char_brace,) /* All options starting from here require argument */ PARM_name , PARM_iname , - USE_FEATURE_FIND_PATH( PARM_path ,) - USE_FEATURE_FIND_REGEX( PARM_regex ,) - USE_FEATURE_FIND_TYPE( PARM_type ,) - USE_FEATURE_FIND_PERM( PARM_perm ,) - USE_FEATURE_FIND_MTIME( PARM_mtime ,) - USE_FEATURE_FIND_MMIN( PARM_mmin ,) - USE_FEATURE_FIND_NEWER( PARM_newer ,) - USE_FEATURE_FIND_INUM( PARM_inum ,) - USE_FEATURE_FIND_USER( PARM_user ,) - USE_FEATURE_FIND_GROUP( PARM_group ,) - USE_FEATURE_FIND_SIZE( PARM_size ,) - USE_FEATURE_FIND_CONTEXT(PARM_context ,) + IF_FEATURE_FIND_PATH( PARM_path ,) + IF_FEATURE_FIND_REGEX( PARM_regex ,) + IF_FEATURE_FIND_TYPE( PARM_type ,) + IF_FEATURE_FIND_PERM( PARM_perm ,) + IF_FEATURE_FIND_MTIME( PARM_mtime ,) + IF_FEATURE_FIND_MMIN( PARM_mmin ,) + IF_FEATURE_FIND_NEWER( PARM_newer ,) + IF_FEATURE_FIND_INUM( PARM_inum ,) + IF_FEATURE_FIND_USER( PARM_user ,) + IF_FEATURE_FIND_GROUP( PARM_group ,) + IF_FEATURE_FIND_SIZE( PARM_size ,) + IF_FEATURE_FIND_CONTEXT(PARM_context ,) }; static const char params[] ALIGN1 = "-a\0" "-o\0" - USE_FEATURE_FIND_NOT( "!\0" ) + IF_FEATURE_FIND_NOT( "!\0" ) #if ENABLE_DESKTOP "-and\0" "-or\0" - USE_FEATURE_FIND_NOT( "-not\0" ) + IF_FEATURE_FIND_NOT( "-not\0" ) #endif "-print\0" - USE_FEATURE_FIND_PRINT0( "-print0\0" ) - USE_FEATURE_FIND_DEPTH( "-depth\0" ) - USE_FEATURE_FIND_PRUNE( "-prune\0" ) - USE_FEATURE_FIND_DELETE( "-delete\0" ) - USE_FEATURE_FIND_EXEC( "-exec\0" ) - USE_FEATURE_FIND_PAREN( "(\0" ) + IF_FEATURE_FIND_PRINT0( "-print0\0" ) + IF_FEATURE_FIND_DEPTH( "-depth\0" ) + IF_FEATURE_FIND_PRUNE( "-prune\0" ) + IF_FEATURE_FIND_DELETE( "-delete\0" ) + IF_FEATURE_FIND_EXEC( "-exec\0" ) + IF_FEATURE_FIND_PAREN( "(\0" ) /* All options starting from here require argument */ "-name\0" "-iname\0" - USE_FEATURE_FIND_PATH( "-path\0" ) - USE_FEATURE_FIND_REGEX( "-regex\0" ) - USE_FEATURE_FIND_TYPE( "-type\0" ) - USE_FEATURE_FIND_PERM( "-perm\0" ) - USE_FEATURE_FIND_MTIME( "-mtime\0" ) - USE_FEATURE_FIND_MMIN( "-mmin\0" ) - USE_FEATURE_FIND_NEWER( "-newer\0" ) - USE_FEATURE_FIND_INUM( "-inum\0" ) - USE_FEATURE_FIND_USER( "-user\0" ) - USE_FEATURE_FIND_GROUP( "-group\0" ) - USE_FEATURE_FIND_SIZE( "-size\0" ) - USE_FEATURE_FIND_CONTEXT("-context\0") + IF_FEATURE_FIND_PATH( "-path\0" ) + IF_FEATURE_FIND_REGEX( "-regex\0" ) + IF_FEATURE_FIND_TYPE( "-type\0" ) + IF_FEATURE_FIND_PERM( "-perm\0" ) + IF_FEATURE_FIND_MTIME( "-mtime\0" ) + IF_FEATURE_FIND_MMIN( "-mmin\0" ) + IF_FEATURE_FIND_NEWER( "-newer\0" ) + IF_FEATURE_FIND_INUM( "-inum\0" ) + IF_FEATURE_FIND_USER( "-user\0" ) + IF_FEATURE_FIND_GROUP( "-group\0" ) + IF_FEATURE_FIND_SIZE( "-size\0" ) + IF_FEATURE_FIND_CONTEXT("-context\0") ; action*** appp; unsigned cur_group = 0; unsigned cur_action = 0; - USE_FEATURE_FIND_NOT( bool invert_flag = 0; ) + IF_FEATURE_FIND_NOT( bool invert_flag = 0; ) /* This is the only place in busybox where we use nested function. * So far more standard alternatives were bigger. */ @@ -530,8 +530,8 @@ appp[cur_group][cur_action++] = ap = xmalloc(sizeof_struct); appp[cur_group][cur_action] = NULL; ap->f = f; - USE_FEATURE_FIND_NOT( ap->invert = invert_flag; ) - USE_FEATURE_FIND_NOT( invert_flag = 0; ) + IF_FEATURE_FIND_NOT( ap->invert = invert_flag; ) + IF_FEATURE_FIND_NOT( invert_flag = 0; ) return ap; } @@ -569,10 +569,10 @@ * it doesn't give smaller code. Other arches? */ /* --- Operators --- */ - if (parm == PARM_a USE_DESKTOP(|| parm == PARM_and)) { + if (parm == PARM_a IF_DESKTOP(|| parm == PARM_and)) { /* no further special handling required */ } - else if (parm == PARM_o USE_DESKTOP(|| parm == PARM_or)) { + else if (parm == PARM_o IF_DESKTOP(|| parm == PARM_or)) { /* start new OR group */ cur_group++; appp = xrealloc(appp, (cur_group+2) * sizeof(*appp)); @@ -581,7 +581,7 @@ cur_action = 0; } #if ENABLE_FEATURE_FIND_NOT - else if (parm == PARM_char_not USE_DESKTOP(|| parm == PARM_not)) { + else if (parm == PARM_char_not IF_DESKTOP(|| parm == PARM_not)) { /* also handles "find ! ! -name 'foo*'" */ invert_flag ^= 1; } @@ -591,13 +591,13 @@ else if (parm == PARM_print) { need_print = 0; /* GNU find ignores '!' here: "find ! -print" */ - USE_FEATURE_FIND_NOT( invert_flag = 0; ) + IF_FEATURE_FIND_NOT( invert_flag = 0; ) (void) ALLOC_ACTION(print); } #if ENABLE_FEATURE_FIND_PRINT0 else if (parm == PARM_print0) { need_print = 0; - USE_FEATURE_FIND_NOT( invert_flag = 0; ) + IF_FEATURE_FIND_NOT( invert_flag = 0; ) (void) ALLOC_ACTION(print0); } #endif @@ -608,7 +608,7 @@ #endif #if ENABLE_FEATURE_FIND_PRUNE else if (parm == PARM_prune) { - USE_FEATURE_FIND_NOT( invert_flag = 0; ) + IF_FEATURE_FIND_NOT( invert_flag = 0; ) (void) ALLOC_ACTION(prune); } #endif @@ -624,7 +624,7 @@ int i; action_exec *ap; need_print = 0; - USE_FEATURE_FIND_NOT( invert_flag = 0; ) + IF_FEATURE_FIND_NOT( invert_flag = 0; ) ap = ALLOC_ACTION(exec); ap->exec_argv = ++argv; /* first arg after -exec */ ap->exec_argc = 0; @@ -813,13 +813,13 @@ { static const char options[] ALIGN1 = "-follow\0" -USE_FEATURE_FIND_XDEV( "-xdev\0" ) -USE_FEATURE_FIND_MAXDEPTH("-mindepth\0""-maxdepth\0") +IF_FEATURE_FIND_XDEV( "-xdev\0" ) +IF_FEATURE_FIND_MAXDEPTH("-mindepth\0""-maxdepth\0") ; enum { OPT_FOLLOW, -USE_FEATURE_FIND_XDEV( OPT_XDEV ,) -USE_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) +IF_FEATURE_FIND_XDEV( OPT_XDEV ,) +IF_FEATURE_FIND_MAXDEPTH(OPT_MINDEPTH,) }; char *arg; Index: findutils/xargs.c =================================================================== --- findutils/xargs.c (revision 26172) +++ findutils/xargs.c (revision 26173) @@ -356,9 +356,9 @@ OPTBIT_UPTO_SIZE, OPTBIT_EOF_STRING, OPTBIT_EOF_STRING1, - USE_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) - USE_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) - USE_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) + IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) + IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) OPT_VERBOSE = 1 << OPTBIT_VERBOSE , OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , @@ -366,14 +366,14 @@ OPT_UPTO_SIZE = 1 << OPTBIT_UPTO_SIZE , OPT_EOF_STRING = 1 << OPTBIT_EOF_STRING , /* GNU: -e[] */ OPT_EOF_STRING1 = 1 << OPTBIT_EOF_STRING1, /* SUS: -E */ - OPT_INTERACTIVE = USE_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, - OPT_TERMINATE = USE_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, - OPT_ZEROTERM = USE_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, + OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, + OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, + OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, }; #define OPTION_STR "+trn:s:e::E:" \ - USE_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ - USE_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ - USE_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") + IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ + IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int xargs_main(int argc, char **argv) @@ -405,7 +405,7 @@ eof_str = NULL; if (opt & OPT_ZEROTERM) - USE_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin); + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin); argv += optind; argc -= optind; Index: findutils/grep.c =================================================================== --- findutils/grep.c (revision 26172) +++ findutils/grep.c (revision 26173) @@ -25,10 +25,10 @@ /* options */ #define OPTSTR_GREP \ "lnqvscFiHhe:f:Lorm:" \ - USE_FEATURE_GREP_CONTEXT("A:B:C:") \ - USE_FEATURE_GREP_EGREP_ALIAS("E") \ - USE_DESKTOP("w") \ - USE_EXTRA_COMPAT("z") \ + IF_FEATURE_GREP_CONTEXT("A:B:C:") \ + IF_FEATURE_GREP_EGREP_ALIAS("E") \ + IF_DESKTOP("w") \ + IF_EXTRA_COMPAT("z") \ "aI" /* ignored: -a "assume all files to be text" */ @@ -51,12 +51,12 @@ OPTBIT_o, /* show only matching parts of lines */ OPTBIT_r, /* recurse dirs */ OPTBIT_m, /* -m MAX_MATCHES */ - USE_FEATURE_GREP_CONTEXT( OPTBIT_A ,) /* -A NUM: after-match context */ - USE_FEATURE_GREP_CONTEXT( OPTBIT_B ,) /* -B NUM: before-match context */ - USE_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */ - USE_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */ - USE_DESKTOP( OPTBIT_w ,) /* whole word match */ - USE_EXTRA_COMPAT( OPTBIT_z ,) /* input is NUL terminated */ + IF_FEATURE_GREP_CONTEXT( OPTBIT_A ,) /* -A NUM: after-match context */ + IF_FEATURE_GREP_CONTEXT( OPTBIT_B ,) /* -B NUM: before-match context */ + IF_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */ + IF_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */ + IF_DESKTOP( OPTBIT_w ,) /* whole word match */ + IF_EXTRA_COMPAT( OPTBIT_z ,) /* input is NUL terminated */ OPT_l = 1 << OPTBIT_l, OPT_n = 1 << OPTBIT_n, OPT_q = 1 << OPTBIT_q, @@ -73,12 +73,12 @@ OPT_o = 1 << OPTBIT_o, OPT_r = 1 << OPTBIT_r, OPT_m = 1 << OPTBIT_m, - OPT_A = USE_FEATURE_GREP_CONTEXT( (1 << OPTBIT_A)) + 0, - OPT_B = USE_FEATURE_GREP_CONTEXT( (1 << OPTBIT_B)) + 0, - OPT_C = USE_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0, - OPT_E = USE_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0, - OPT_w = USE_DESKTOP( (1 << OPTBIT_w)) + 0, - OPT_z = USE_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0, + OPT_A = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_A)) + 0, + OPT_B = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_B)) + 0, + OPT_C = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0, + OPT_E = IF_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0, + OPT_w = IF_DESKTOP( (1 << OPTBIT_w)) + 0, + OPT_z = IF_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0, }; #define PRINT_FILES_WITH_MATCHES (option_mask32 & OPT_l) @@ -105,7 +105,7 @@ int lines_before; int lines_after; char **before_buf; - USE_EXTRA_COMPAT(size_t *before_buf_size;) + IF_EXTRA_COMPAT(size_t *before_buf_size;) int last_line_printed; #endif /* globals used internally */ @@ -400,7 +400,7 @@ /* Add the line to the circular 'before' buffer */ free(before_buf[curpos]); before_buf[curpos] = line; - USE_EXTRA_COMPAT(before_buf_size[curpos] = line_len;) + IF_EXTRA_COMPAT(before_buf_size[curpos] = line_len;) curpos = (curpos + 1) % lines_before; /* avoid free(line) - we took the line */ line = NULL; @@ -544,7 +544,7 @@ lines_after = 0; } else if (lines_before > 0) { before_buf = xzalloc(lines_before * sizeof(before_buf[0])); - USE_EXTRA_COMPAT(before_buf_size = xzalloc(lines_before * sizeof(before_buf_size[0]));) + IF_EXTRA_COMPAT(before_buf_size = xzalloc(lines_before * sizeof(before_buf_size[0]));) } #else /* with auto sanity checks */ Index: mailutils/popmaildir.c =================================================================== --- mailutils/popmaildir.c (revision 26172) +++ mailutils/popmaildir.c (revision 26173) @@ -73,9 +73,9 @@ // parse options opt_complementary = "-1:dd:t+:R+:L+:H+"; opts = getopt32(argv, - "bdmVcasTkt:" "R:Z:L:H:" USE_FEATURE_POPMAILDIR_DELIVERY("M:F:"), + "bdmVcasTkt:" "R:Z:L:H:" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"), &timeout, NULL, NULL, NULL, &opt_nlines - USE_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same + IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same ); //argc -= optind; argv += optind; Index: mailutils/mime.c =================================================================== --- mailutils/mime.c (revision 26172) +++ mailutils/mime.c (revision 26173) @@ -341,11 +341,11 @@ // parse options // N.B. only -x and -X are supported so far - opt_complementary = "x--X:X--x" USE_FEATURE_REFORMIME_COMPAT(":m::"); + opt_complementary = "x--X:X--x" IF_FEATURE_REFORMIME_COMPAT(":m::"); opts = getopt32(argv, - "x:X" USE_FEATURE_REFORMIME_COMPAT("deis:r:c:m:h:o:O:"), + "x:X" IF_FEATURE_REFORMIME_COMPAT("deis:r:c:m:h:o:O:"), &opt_prefix - USE_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL) + IF_FEATURE_REFORMIME_COMPAT(, NULL, NULL, &G.opt_charset, NULL, NULL, NULL, NULL) ); //argc -= optind; argv += optind; Index: procps/pidof.c =================================================================== --- procps/pidof.c (revision 26172) +++ procps/pidof.c (revision 26173) @@ -10,10 +10,10 @@ #include "libbb.h" enum { - USE_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,) - USE_FEATURE_PIDOF_OMIT( OPTBIT_OMIT ,) - OPT_SINGLE = USE_FEATURE_PIDOF_SINGLE((1< 0) { // if the insert is before "dot" then we need to update Index: editors/cmp.c =================================================================== --- editors/cmp.c (revision 26172) +++ editors/cmp.c (revision 26173) @@ -37,7 +37,7 @@ { FILE *fp1, *fp2, *outfile = stdout; const char *filename1, *filename2 = "-"; - USE_DESKTOP(off_t skip1 = 0, skip2 = 0;) + IF_DESKTOP(off_t skip1 = 0, skip2 = 0;) off_t char_pos = 0; int line_pos = 1; /* Hopefully won't overflow... */ const char *fmt; @@ -48,8 +48,8 @@ xfunc_error_retval = 2; /* 1 is returned if files are different. */ opt_complementary = "-1" - USE_DESKTOP(":?4") - SKIP_DESKTOP(":?2") + IF_DESKTOP(":?4") + IF_NOT_DESKTOP(":?2") ":l--s:s--l"; opt = getopt32(argv, opt_chars); argv += optind; Index: editors/diff.c =================================================================== --- editors/diff.c (revision 26172) +++ editors/diff.c (revision 26173) @@ -103,8 +103,8 @@ smallint exit_status; int opt_U_context; size_t max_context; /* size of context_vec_start */ - USE_FEATURE_DIFF_DIR(int dl_count;) - USE_FEATURE_DIFF_DIR(char **dl;) + IF_FEATURE_DIFF_DIR(int dl_count;) + IF_FEATURE_DIFF_DIR(char **dl;) char *opt_S_start; const char *label1; const char *label2; Index: util-linux/fdisk.c =================================================================== --- util-linux/fdisk.c (revision 26172) +++ util-linux/fdisk.c (revision 26173) @@ -17,7 +17,7 @@ /* Looks like someone forgot to add this to config system */ #ifndef ENABLE_FEATURE_FDISK_BLKSIZE # define ENABLE_FEATURE_FDISK_BLKSIZE 0 -# define USE_FEATURE_FDISK_BLKSIZE(a) +# define IF_FEATURE_FDISK_BLKSIZE(a) #endif #define DEFAULT_SECTOR_SIZE 512 @@ -1302,7 +1302,7 @@ // or get_boot() [table is bad] -> create_sunlabel() -> get_boot(CREATE_EMPTY_SUN). // (just factor out re-init of ptes[0,1,2,3] in a separate fn instead?) // So skip opening device _again_... - if (what == CREATE_EMPTY_DOS USE_FEATURE_SUN_LABEL(|| what == CREATE_EMPTY_SUN)) + if (what == CREATE_EMPTY_DOS IF_FEATURE_SUN_LABEL(|| what == CREATE_EMPTY_SUN)) goto created_table; fd = open(disk_device, (option_mask32 & OPT_l) ? O_RDONLY : O_RDWR); @@ -1372,7 +1372,7 @@ "partition table, nor Sun, SGI or OSF " "disklabel\n"); #ifdef __sparc__ - USE_FEATURE_SUN_LABEL(create_sunlabel();) + IF_FEATURE_SUN_LABEL(create_sunlabel();) #else create_doslabel(); #endif @@ -1385,7 +1385,7 @@ #endif /* FEATURE_FDISK_WRITABLE */ - USE_FEATURE_FDISK_WRITABLE(warn_cylinders();) + IF_FEATURE_FDISK_WRITABLE(warn_cylinders();) warn_geometry(); for (i = 0; i < 4; i++) { @@ -1406,7 +1406,7 @@ pe->sectorbuffer[510], pe->sectorbuffer[511], i + 1); - USE_FEATURE_FDISK_WRITABLE(pe->changed = 1;) + IF_FEATURE_FDISK_WRITABLE(pe->changed = 1;) } } @@ -2797,7 +2797,7 @@ close_dev_fd(); /* needed: fd 3 must not stay closed */ opt_complementary = "b+:C+:H+:S+"; /* numeric params */ - opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), + opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"), §or_size, &user_cylinders, &user_heads, &user_sectors); argc -= optind; argv += optind; Index: util-linux/hexdump.c =================================================================== --- util-linux/hexdump.c (revision 26172) +++ util-linux/hexdump.c (revision 26173) @@ -41,7 +41,7 @@ static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; -static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" USE_FEATURE_HEXDUMP_REVERSE("R"); +static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" IF_FEATURE_HEXDUMP_REVERSE("R"); static const struct suffix_mult suffixes[] = { { "b", 512 }, Index: util-linux/acpid.c =================================================================== --- util-linux/acpid.c (revision 26172) +++ util-linux/acpid.c (revision 26173) @@ -61,9 +61,9 @@ const char *opt_logfile = "/var/log/acpid.log"; getopt32(argv, "c:e:l:d" - USE_FEATURE_ACPID_COMPAT("g:m:s:S:v"), + IF_FEATURE_ACPID_COMPAT("g:m:s:S:v"), &opt_conf, &opt_input, &opt_logfile - USE_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL, NULL) + IF_FEATURE_ACPID_COMPAT(, NULL, NULL, NULL, NULL, NULL) ); // daemonize unless -d given Index: util-linux/mount.c =================================================================== --- util-linux/mount.c (revision 26172) +++ util-linux/mount.c (revision 26173) @@ -105,22 +105,22 @@ static const int32_t mount_options[] = { // MS_FLAGS set a bit. ~MS_FLAGS disable that bit. 0 flags are NOPs. - USE_FEATURE_MOUNT_LOOP( + IF_FEATURE_MOUNT_LOOP( /* "loop" */ 0, ) - USE_FEATURE_MOUNT_FSTAB( + IF_FEATURE_MOUNT_FSTAB( /* "defaults" */ 0, /* "quiet" 0 - do not filter out, vfat wants to see it */ /* "noauto" */ MOUNT_NOAUTO, /* "sw" */ MOUNT_SWAP, /* "swap" */ MOUNT_SWAP, - USE_DESKTOP(/* "user" */ MOUNT_USERS,) - USE_DESKTOP(/* "users" */ MOUNT_USERS,) + IF_DESKTOP(/* "user" */ MOUNT_USERS,) + IF_DESKTOP(/* "users" */ MOUNT_USERS,) /* "_netdev" */ 0, ) - USE_FEATURE_MOUNT_FLAGS( + IF_FEATURE_MOUNT_FLAGS( // vfs flags /* "nosuid" */ MS_NOSUID, /* "suid" */ ~MS_NOSUID, @@ -161,20 +161,20 @@ }; static const char mount_option_str[] = - USE_FEATURE_MOUNT_LOOP( + IF_FEATURE_MOUNT_LOOP( "loop\0" ) - USE_FEATURE_MOUNT_FSTAB( + IF_FEATURE_MOUNT_FSTAB( "defaults\0" // "quiet\0" - do not filter out, vfat wants to see it "noauto\0" "sw\0" "swap\0" - USE_DESKTOP("user\0") - USE_DESKTOP("users\0") + IF_DESKTOP("user\0") + IF_DESKTOP("users\0") "_netdev\0" ) - USE_FEATURE_MOUNT_FLAGS( + IF_FEATURE_MOUNT_FLAGS( // vfs flags "nosuid\0" "suid\0" @@ -1781,9 +1781,9 @@ int i, j, rc = 0; unsigned opt; struct mntent mtpair[2], *mtcur = mtpair; - SKIP_DESKTOP(const int nonroot = 0;) + IF_NOT_DESKTOP(const int nonroot = 0;) - USE_DESKTOP(int nonroot = ) sanitize_env_if_suid(); + IF_DESKTOP(int nonroot = ) sanitize_env_if_suid(); // Parse long options, like --bind and --move. Note that -o option // and --option are synonymous. Yes, this means --remount,rw works. @@ -1797,9 +1797,9 @@ // Parse remaining options // Max 2 params; -o is a list, -v is a counter - opt_complementary = "?2o::" USE_FEATURE_MOUNT_VERBOSE("vv"); + opt_complementary = "?2o::" IF_FEATURE_MOUNT_VERBOSE("vv"); opt = getopt32(argv, OPTION_STR, &lst_o, &fstype, &O_optmatch - USE_FEATURE_MOUNT_VERBOSE(, &verbose)); + IF_FEATURE_MOUNT_VERBOSE(, &verbose)); while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w Index: util-linux/fsck_minix.c =================================================================== --- util-linux/fsck_minix.c (revision 26172) +++ util-linux/fsck_minix.c (revision 26173) @@ -151,7 +151,7 @@ char superblock_buffer[BLOCK_SIZE]; char add_zone_ind_blk[BLOCK_SIZE]; char add_zone_dind_blk[BLOCK_SIZE]; - USE_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];) + IF_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];) char check_file_blk[BLOCK_SIZE]; /* File-name data */ ------------------------------------------------------------------------ r26172 | vda | 2009-04-20 19:52:21 -0500 (Mon, 20 Apr 2009) | 8 lines Changed paths: M /trunk/busybox/archival/libunarchive/data_extract_all.c M /trunk/busybox/archival/tar.c M /trunk/busybox/include/unarchive.h tar: support for tar --numeric-owner. By Natanael Copa. function old new delta tar_longopts 221 237 +16 data_extract_all 692 705 +13 tar_main 690 702 +12 ------------------------------------------------------------------------ Index: archival/tar.c =================================================================== --- archival/tar.c (revision 26171) +++ archival/tar.c (revision 26172) @@ -738,6 +738,7 @@ USE_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) OPTBIT_NOPRESERVE_OWN, OPTBIT_NOPRESERVE_PERM, + OPTBIT_NUMERIC_OWNER, OPT_TEST = 1 << 0, // t OPT_EXTRACT = 1 << 1, // x OPT_BASEDIR = 1 << 2, // C @@ -756,6 +757,7 @@ OPT_COMPRESS = USE_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z OPT_NOPRESERVE_OWN = 1 << OPTBIT_NOPRESERVE_OWN , // no-same-owner OPT_NOPRESERVE_PERM = 1 << OPTBIT_NOPRESERVE_PERM, // no-same-permissions + OPT_NUMERIC_OWNER = 1 << OPTBIT_NUMERIC_OWNER, }; #if ENABLE_FEATURE_TAR_LONG_OPTIONS static const char tar_longopts[] ALIGN1 = @@ -787,6 +789,7 @@ # if ENABLE_FEATURE_SEAMLESS_Z "compress\0" No_argument "Z" # endif + "numeric-owner\0" No_argument "\xfc" "no-same-owner\0" No_argument "\xfd" "no-same-permissions\0" No_argument "\xfe" /* --exclude takes next bit position in option mask, */ @@ -873,6 +876,9 @@ if (opt & OPT_NOPRESERVE_PERM) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_PERM; + if (opt & OPT_NUMERIC_OWNER) + tar_handle->ah_flags |= ARCHIVE_NUMERIC_OWNER; + if (opt & OPT_GZIP) get_header_ptr = get_header_tar_gz; Index: archival/libunarchive/data_extract_all.c =================================================================== --- archival/libunarchive/data_extract_all.c (revision 26171) +++ archival/libunarchive/data_extract_all.c (revision 26172) @@ -114,22 +114,24 @@ } if (!(archive_handle->ah_flags & ARCHIVE_NOPRESERVE_OWN)) { -#if ENABLE_FEATURE_TAR_UNAME_GNAME - uid_t uid = file_header->uid; - gid_t gid = file_header->gid; + if (ENABLE_FEATURE_TAR_UNAME_GNAME + && !(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER) + ) { + uid_t uid = file_header->uid; + gid_t gid = file_header->gid; - if (file_header->uname) { - struct passwd *pwd = getpwnam(file_header->uname); - if (pwd) uid = pwd->pw_uid; + if (file_header->uname) { + struct passwd *pwd = getpwnam(file_header->uname); + if (pwd) uid = pwd->pw_uid; + } + if (file_header->gname) { + struct group *grp = getgrnam(file_header->gname); + if (grp) gid = grp->gr_gid; + } + lchown(file_header->name, uid, gid); + } else { + lchown(file_header->name, file_header->uid, file_header->gid); } - if (file_header->gname) { - struct group *grp = getgrnam(file_header->gname); - if (grp) gid = grp->gr_gid; - } - lchown(file_header->name, uid, gid); -#else - lchown(file_header->name, file_header->uid, file_header->gid); -#endif } if ((file_header->mode & S_IFMT) != S_IFLNK) { /* uclibc has no lchmod, glibc is even stranger - Index: include/unarchive.h =================================================================== --- include/unarchive.h (revision 26171) +++ include/unarchive.h (revision 26172) @@ -11,6 +11,7 @@ #define ARCHIVE_EXTRACT_NEWER 16 #define ARCHIVE_NOPRESERVE_OWN 32 #define ARCHIVE_NOPRESERVE_PERM 64 +#define ARCHIVE_NUMERIC_OWNER 128 typedef struct file_header_t { char *name; ------------------------------------------------------------------------ r26171 | vda | 2009-04-20 19:41:57 -0500 (Mon, 20 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/networking/udhcp/leases.c udhcpc: fix truncation of last char in client hostnames ------------------------------------------------------------------------ Index: networking/udhcp/leases.c =================================================================== --- networking/udhcp/leases.c (revision 26170) +++ networking/udhcp/leases.c (revision 26171) @@ -63,7 +63,8 @@ if (oldest) { oldest->hostname[0] = '\0'; if (hostname) { - hostname_length = hostname[-1]; /* look at option size byte */ + /* option size byte, + 1 for NUL */ + hostname_length = hostname[-1] + 1; if (hostname_length > sizeof(oldest->hostname)) hostname_length = sizeof(oldest->hostname); hostname = (uint8_t*) safe_strncpy((char*)oldest->hostname, (char*)hostname, hostname_length); ------------------------------------------------------------------------ r26170 | vda | 2009-04-20 19:29:17 -0500 (Mon, 20 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/switch_root.c switch_root: print errno on failure ------------------------------------------------------------------------ Index: util-linux/switch_root.c =================================================================== --- util-linux/switch_root.c (revision 26169) +++ util-linux/switch_root.c (revision 26170) @@ -97,7 +97,7 @@ // Overmount / with newdir and chroot into it. The chdir is needed to // recalculate "." and ".." links. if (mount(".", "/", NULL, MS_MOVE, NULL)) - bb_error_msg_and_die("error moving root"); + bb_perror_msg_and_die("error moving root"); xchroot("."); xchdir("/"); ------------------------------------------------------------------------ r26169 | vda | 2009-04-20 19:17:00 -0500 (Mon, 20 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/examples/udhcp/simple.script tweak example udhcp script ------------------------------------------------------------------------ Index: examples/udhcp/simple.script =================================================================== --- examples/udhcp/simple.script (revision 26168) +++ examples/udhcp/simple.script (revision 26169) @@ -1,10 +1,10 @@ #!/bin/sh - # udhcpc script edited by Tim Riker -[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 +RESOLV_CONF="/etc/resolv.conf" -RESOLV_CONF="/etc/resolv.conf" +[ -n "$1" ] || echo "Error: should be called from udhcpc" && exit 1 + NETMASK="" [ -n "$subnet" ] && NETMASK="netmask $subnet" BROADCAST="broadcast +" @@ -35,10 +35,10 @@ echo "Recreating $RESOLV_CONF" echo -n > $RESOLV_CONF-$$ - [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF-$$ + [ -n "$domain" ] && echo "search $domain" >> $RESOLV_CONF-$$ for i in $dns ; do echo " Adding DNS server $i" - echo nameserver $i >> $RESOLV_CONF-$$ + echo "nameserver $i" >> $RESOLV_CONF-$$ done mv $RESOLV_CONF-$$ $RESOLV_CONF ;; ------------------------------------------------------------------------ r26167 | vda | 2009-04-20 17:04:21 -0500 (Mon, 20 Apr 2009) | 8 lines Changed paths: M /trunk/busybox/shell/Config.in M /trunk/busybox/shell/hush.c A /trunk/busybox/shell/hush_test/hush-misc/export-n.right A /trunk/busybox/shell/hush_test/hush-misc/export-n.tests hush: export -n support function old new delta builtin_export 206 256 +50 set_local_var 248 265 +17 expand_variables 2204 2203 -1 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26166) +++ shell/hush.c (revision 26167) @@ -1253,10 +1253,10 @@ /* str holds "NAME=VAL" and is expected to be malloced. * We take ownership of it. * flg_export: - * 0: do not export - * 1: export - * -1: if NAME is set, leave export status alone - * if NAME is not set, do not export + * 0: do not change export flag + * (if creating new variable, flag will be 0) + * 1: set export flag and putenv the variable + * -1: clear export flag and unsetenv the variable * flg_read_only is set only when we handle -R var=val */ #if BB_MMU @@ -1297,6 +1297,7 @@ free(str); return -1; } +//TODO: optimize out redundant unsetenv/putenv's? debug_printf_env("%s: unsetenv '%s'\n", __func__, str); unsetenv(str); /* just in case */ *value = '='; @@ -1331,8 +1332,13 @@ if (flg_export == 1) cur->flg_export = 1; if (cur->flg_export) { - debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr); - return putenv(cur->varstr); + if (flg_export == -1) { + cur->flg_export = 0; + /* unsetenv was already done */ + } else { + debug_printf_env("%s: putenv '%s'\n", __func__, cur->varstr); + return putenv(cur->varstr); + } } return 0; } @@ -2214,7 +2220,7 @@ val = NULL; } else { char *new_var = xasprintf("%s=%s", var, val); - set_local_var(new_var, -1, 0); + set_local_var(new_var, 0, 0); } } } @@ -6400,7 +6406,9 @@ static int builtin_export(char **argv) { - if (*++argv == NULL) { + unsigned opt_unexport; + + if (argv[1] == NULL) { char **e = environ; if (e) { while (*e) { @@ -6426,15 +6434,33 @@ return EXIT_SUCCESS; } +#if ENABLE_HUSH_EXPORT_N + opt_unexport = getopt32(argv, "+n"); /* "+": stop at 1st non-option */ + argv += optind; +#else + opt_unexport = 0; + argv++; +#endif + do { char *name = *argv; - /* So far we do not check that name is valid */ + /* So far we do not check that name is valid (TODO?) */ + if (strchr(name, '=') == NULL) { - /* Exporting a name without a =VALUE */ struct variable *var; var = get_local_var(name); + if (opt_unexport) { + /* export -n NAME (without =VALUE) */ + if (var) { + var->flg_export = 0; + debug_printf_env("%s: unsetenv '%s'\n", __func__, name); + unsetenv(name); + } /* else: export -n NOT_EXISTING_VAR: no-op */ + continue; + } + /* export NAME (without =VALUE) */ if (var) { var->flg_export = 1; debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); @@ -6448,10 +6474,13 @@ * We just set it to "" and export. */ name = xasprintf("%s=", name); } else { - /* Exporting VAR=VALUE */ + /* (Un)exporting NAME=VALUE */ name = xstrdup(name); } - set_local_var(name, 1, 0); + set_local_var(name, + /*export:*/ (opt_unexport ? -1 : 1), + /*readonly:*/ 0 + ); } while (*++argv); return EXIT_SUCCESS; Index: shell/hush_test/hush-misc/export-n.right =================================================================== --- shell/hush_test/hush-misc/export-n.right (revision 0) +++ shell/hush_test/hush-misc/export-n.right (revision 26167) @@ -0,0 +1,10 @@ +export aaa1="'''" +export aaa2='' +export aaa3="'''"'abc' +export aaa8='8' +aaa9=9 +aaa10=10 +Nothing: +Nothing: +Nothing: +Done Index: shell/hush_test/hush-misc/export-n.tests =================================================================== --- shell/hush_test/hush-misc/export-n.tests (revision 0) +++ shell/hush_test/hush-misc/export-n.tests (revision 26167) @@ -0,0 +1,37 @@ +export aaa1="'''" +export aaa2="" +export aaa3="'''abc" +export | grep aaa.= + +export -n aaa1 +unset aaa2; export -n aaa2="ghi" +export -n aaa3="klm" +export | grep aaa.= + +export aaa4=4 aaa5=5 +export -n aaa4=4n +export -n aaa5 +export | grep aaa.= + +export aaa5=5 aaa6=6 aaa7=7 aaa8=8 +export -n aaa5 aaa6=6n aaa7 +export | grep aaa.= + +aaa9=9 +export -n aaa9 +set | grep ^aaa9= + +export aaa10=10 +export -n aaa10 +set | grep ^aaa10= + + +export EXPORTED=qwe +export -nnnnnn nnnnnn; echo "Nothing:"; env | grep nnnnnn + +export -n EXPORTED=123; echo "Nothing:"; env | grep ^EXPORTED + +export EXPORTED=qwe +export -n EXPORTED; EXPORTED=123; echo "Nothing:"; env | grep ^EXPORTED + +echo Done Property changes on: shell/hush_test/hush-misc/export-n.tests ___________________________________________________________________ Name: svn:executable + * Index: shell/Config.in =================================================================== --- shell/Config.in (revision 26166) +++ shell/Config.in (revision 26167) @@ -232,6 +232,13 @@ help Enable support for shell functions in hush. +800 bytes. +config HUSH_EXPORT_N + bool "Support export '-n' option" + default n + depends on HUSH + help + Enable support for export '-n' option in hush. It is a bash extension. + config LASH bool "lash (deprecated: aliased to hush)" default n ------------------------------------------------------------------------ r26166 | vda | 2009-04-20 05:52:31 -0500 (Mon, 20 Apr 2009) | 3 lines Changed paths: A /trunk/busybox/shell/hush_test/hush-bugs/env_and_func.right A /trunk/busybox/shell/hush_test/hush-bugs/env_and_func.tests A /trunk/busybox/shell/hush_test/hush-misc/func_args1.right A /trunk/busybox/shell/hush_test/hush-misc/func_args1.tests hush: add two testcases ------------------------------------------------------------------------ Index: shell/hush_test/hush-misc/func_args1.right =================================================================== --- shell/hush_test/hush-misc/func_args1.right (revision 0) +++ shell/hush_test/hush-misc/func_args1.right (revision 26166) @@ -0,0 +1,5 @@ +params: a b c +'f 1 2 3' called +params: a b c +'f 1 2 3' called +params: a b c Index: shell/hush_test/hush-misc/func_args1.tests =================================================================== --- shell/hush_test/hush-misc/func_args1.tests (revision 0) +++ shell/hush_test/hush-misc/func_args1.tests (revision 26166) @@ -0,0 +1,10 @@ +# UNFIXED BUG + +f() { echo "'f $1 $2 $3' called"; } + +set -- a b c +echo "params: $1 $2 $3" +f 1 2 3 +echo "params: $1 $2 $3" +true | f 1 2 3 +echo "params: $1 $2 $3" Property changes on: shell/hush_test/hush-misc/func_args1.tests ___________________________________________________________________ Name: svn:executable + * Index: shell/hush_test/hush-bugs/env_and_func.right =================================================================== --- shell/hush_test/hush-bugs/env_and_func.right (revision 0) +++ shell/hush_test/hush-bugs/env_and_func.right (revision 26166) @@ -0,0 +1,2 @@ +var=val +var=old Index: shell/hush_test/hush-bugs/env_and_func.tests =================================================================== --- shell/hush_test/hush-bugs/env_and_func.tests (revision 0) +++ shell/hush_test/hush-bugs/env_and_func.tests (revision 26166) @@ -0,0 +1,6 @@ +# UNFIXED BUG + +var=old +f() { echo "var=$var"; } +var=val f +echo "var=$var" Property changes on: shell/hush_test/hush-bugs/env_and_func.tests ___________________________________________________________________ Name: svn:executable + * ------------------------------------------------------------------------ r26165 | vda | 2009-04-20 04:26:17 -0500 (Mon, 20 Apr 2009) | 7 lines Changed paths: M /trunk/busybox/miscutils/watchdog.c watchdog: enable it before setting timeout function old new delta watchdog_main 239 259 +20 static.enable - 4 +4 ------------------------------------------------------------------------ Index: miscutils/watchdog.c =================================================================== --- miscutils/watchdog.c (revision 26164) +++ miscutils/watchdog.c (revision 26165) @@ -59,13 +59,20 @@ /* WDIOC_SETTIMEOUT takes seconds, not milliseconds */ htimer_duration = htimer_duration / 1000; #ifndef WDIOC_SETTIMEOUT -#error WDIOC_SETTIMEOUT is not defined, cannot compile watchdog applet +# error WDIOC_SETTIMEOUT is not defined, cannot compile watchdog applet #else +# if defined WDIOC_SETOPTIONS && defined WDIOS_ENABLECARD + { + static const int enable = WDIOS_ENABLECARD; + ioctl_or_warn(3, WDIOC_SETOPTIONS, (void*) &enable); + } +# endif ioctl_or_warn(3, WDIOC_SETTIMEOUT, &htimer_duration); #endif + #if 0 ioctl_or_warn(3, WDIOC_GETTIMEOUT, &htimer_duration); - printf("watchdog: SW timer is %dms, HW timer is %dms\n", + printf("watchdog: SW timer is %dms, HW timer is %ds\n", stimer_duration, htimer_duration * 1000); #endif ------------------------------------------------------------------------ r26164 | vda | 2009-04-19 19:34:01 -0500 (Sun, 19 Apr 2009) | 6 lines Changed paths: M /trunk/busybox/shell/hush.c A /trunk/busybox/shell/hush_test/hush-misc/redir5.right A /trunk/busybox/shell/hush_test/hush-misc/redir5.tests hush: fix stdin of backgrounded pipe function old new delta run_list 2450 2502 +52 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26163) +++ shell/hush.c (revision 26164) @@ -3369,7 +3369,6 @@ static const char *const null_ptr = NULL; int i; int nextin; - int pipefds[2]; /* pipefds[0] is for reading */ struct command *command; char **argv_expanded; char **argv; @@ -3552,6 +3551,7 @@ nextin = 0; for (i = 0; i < pi->num_cmds; i++) { + struct fd_pair pipefds; #if !BB_MMU volatile nommu_save_t nommu_save; nommu_save.new_env = NULL; @@ -3568,10 +3568,10 @@ } /* pipes are inserted between pairs of commands */ - pipefds[0] = 0; - pipefds[1] = 1; + pipefds.rd = 0; + pipefds.wr = 1; if ((i + 1) < pi->num_cmds) - xpipe(pipefds); + xpiped_pair(pipefds); command->pid = BB_MMU ? fork() : vfork(); if (!command->pid) { /* child */ @@ -3592,10 +3592,18 @@ } } #endif - xmove_fd(nextin, 0); - xmove_fd(pipefds[1], 1); /* write end */ - if (pipefds[0] > 1) - close(pipefds[0]); /* read end */ + if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) { + /* 1st cmd in backgrounded pipe + * should have its stdin /dev/null'ed */ + close(0); + if (open(bb_dev_null, O_RDONLY)) + xopen("/", O_RDONLY); + } else { + xmove_fd(nextin, 0); + } + xmove_fd(pipefds.wr, 1); + if (pipefds.rd > 1) + close(pipefds.rd); /* Like bash, explicit redirects override pipes, * and the pipe fd is available for dup'ing. */ if (setup_redirects(command, NULL)) @@ -3640,9 +3648,9 @@ if (i) close(nextin); if ((i + 1) < pi->num_cmds) - close(pipefds[1]); /* write end */ + close(pipefds.wr); /* Pass read (output) pipe end to next iteration */ - nextin = pipefds[0]; + nextin = pipefds.rd; } if (!pi->alive_cmds) { Index: shell/hush_test/hush-misc/redir5.tests =================================================================== --- shell/hush_test/hush-misc/redir5.tests (revision 0) +++ shell/hush_test/hush-misc/redir5.tests (revision 26164) @@ -0,0 +1,13 @@ +echo "Backgrounded pipes shall have their stdin redirected to /dev/null" + +# 1. bash does not redirect stdin to /dev/null if it is interactive. +# hush does it always (this is allowed by standards). + +# 2. Failure will result in this script hanging + +cat & wait; echo Zero:$? + +# This does not work for bash! bash bug? +cat | cat & wait; echo Zero:$? + +echo Done Property changes on: shell/hush_test/hush-misc/redir5.tests ___________________________________________________________________ Name: svn:executable + * Index: shell/hush_test/hush-misc/redir5.right =================================================================== --- shell/hush_test/hush-misc/redir5.right (revision 0) +++ shell/hush_test/hush-misc/redir5.right (revision 26164) @@ -0,0 +1,4 @@ +Backgrounded pipes shall have their stdin redirected to /dev/null +Zero:0 +Zero:0 +Done ------------------------------------------------------------------------ r26163 | vda | 2009-04-19 18:38:08 -0500 (Sun, 19 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/mdev.c mdev: enlarge inline documentation ------------------------------------------------------------------------ Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26162) +++ util-linux/mdev.c (revision 26163) @@ -15,6 +15,8 @@ * contains "4:0\n". Directory name is taken as device name, path component * directly after /sys/class/ as subsystem. In this example, "tty0" and "tty". * Then mdev creates the /dev/device_name node. + * If /sys/class/.../dev file does not exist, mdev still may act + * on this device: see "@|$|*command args..." parameter in config file. * * mdev w/o parameters is called as hotplug helper. It takes device * and subsystem names from $DEVPATH and $SUBSYSTEM, extracts @@ -29,20 +31,34 @@ * * [-][subsystem/]device user:grp mode [>|=path] [@|$|*command args...] * [-]@maj,min[-min2] user:grp mode [>|=path] [@|$|*command args...] + * [-]$envvar=val user:grp mode [>|=path] [@|$|*command args...] * - * The device name or "subsystem/device" combo is matched against 1st field - * (which is a regex), or maj,min is matched against 1st field. - * * Leading minus in 1st field means "don't stop on this line", otherwise * search is stopped after the matching line is encountered. * - * When line matches, the device node is created, chmod'ed and chown'ed. - * Then it moved to path, and if >path, a symlink to moved node is created + * The device name or "subsystem/device" combo is matched against 1st field + * (which is a regex), or maj,min is matched against 1st field, + * or specified environment variable (as regex) is matched against 1st field. + * + * $envvar=val format is useful for loading modules for hot-plugged devices + * which do not have driver loaded yet. In this case /sys/class/.../dev + * does not exist, but $MODALIAS is set to needed module's name + * (actually, an alias to it) by kernel. This rule instructs mdev + * to load the module and exit: + * $MODALIAS=.* 0:0 660 @modprobe "$MODALIAS" + * The kernel will generate another hotplug event when /sys/class/.../dev + * file appears. + * + * When line matches, the device node is created, chmod'ed and chown'ed, + * moved to path, and if >path, a symlink to moved node is created, + * all this if /sys/class/.../dev exists. * Examples: * =loop/ - moves to /dev/loop * >disk/sda%1 - moves to /dev/disk/sdaN, makes /dev/sdaN a symlink - * Then "command args" is executed (via sh -c 'command args'). + * + * Then "command args..." is executed (via sh -c 'command args...'). * @:execute on creation, $:on deletion, *:on both. + * This happens regardless of /sys/class/.../dev existence. */ struct globals { ------------------------------------------------------------------------ r26162 | vda | 2009-04-19 18:07:51 -0500 (Sun, 19 Apr 2009) | 9 lines Changed paths: M /trunk/busybox/shell/hush.c M /trunk/busybox/shell/hush_leaktool.sh M /trunk/busybox/shell/hush_test/hush-trap/catch.right M /trunk/busybox/shell/hush_test/hush-z_slow/leak_all1.tests hush: fix "export not_yet_defined_var", fix parsing of "cmd | }" corner case; improve hush_leaktool.sh; fix some false positives in testsuite function old new delta builtin_export 191 206 +15 parse_stream 2196 2200 +4 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26161) +++ shell/hush.c (revision 26162) @@ -4459,10 +4459,6 @@ } } command->argv = add_string_to_strings(command->argv, xstrdup(word->data)); -//SEGV, but good idea. -// command->argv = add_string_to_strings(command->argv, word->data); -// word->data = NULL; -// word->length = 0; debug_print_strings("word appended to argv", command->argv); } @@ -5481,14 +5477,16 @@ * } is an ordinary char in this case, even inside { cmd; } * Pathological example: { ""}; } should exec "}" cmd */ - if (ch == '}' - && !(IS_NULL_PIPE(ctx.pipe) - && IS_NULL_CMD(ctx.command) - && dest.length == 0 - && !dest.o_quoted - ) - ) { - goto ordinary_char; + if (ch == '}') { + if (!IS_NULL_CMD(ctx.command) /* cmd } */ + || dest.length != 0 /* word} */ + || dest.o_quoted /* ""} */ + ) { + goto ordinary_char; + } + if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */ + goto skip_end_trigger; + /* else: } does terminate a group */ } if (end_trigger && end_trigger == ch @@ -5531,6 +5529,7 @@ return ctx.list_head; } } + skip_end_trigger: if (is_ifs) continue; @@ -6420,12 +6419,11 @@ } do { - const char *value; char *name = *argv; - value = strchr(name, '='); - if (!value) { - /* They are exporting something without a =VALUE */ + /* So far we do not check that name is valid */ + if (strchr(name, '=') == NULL) { + /* Exporting a name without a =VALUE */ struct variable *var; var = get_local_var(name); @@ -6433,12 +6431,19 @@ var->flg_export = 1; debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr); putenv(var->varstr); + continue; } - /* bash does not return an error when trying to export - * an undefined variable. Do likewise. */ - continue; + /* Exporting non-existing variable. + * bash does not put it in environment, + * but remembers that it is exported, + * and does put it in env when it is set later. + * We just set it to "" and export. */ + name = xasprintf("%s=", name); + } else { + /* Exporting VAR=VALUE */ + name = xstrdup(name); } - set_local_var(xstrdup(name), 1, 0); + set_local_var(name, 1, 0); } while (*++argv); return EXIT_SUCCESS; Index: shell/hush_test/hush-z_slow/leak_all1.tests =================================================================== --- shell/hush_test/hush-z_slow/leak_all1.tests (revision 26161) +++ shell/hush_test/hush-z_slow/leak_all1.tests (revision 26162) @@ -67,6 +67,7 @@ f >/dev/null : $((i++)) done +unset -f f memleak @@ -133,6 +134,7 @@ f >/dev/null : $((i++)) done +unset -f f memleak Index: shell/hush_test/hush-trap/catch.right =================================================================== --- shell/hush_test/hush-trap/catch.right (revision 26161) +++ shell/hush_test/hush-trap/catch.right (revision 26162) @@ -2,3 +2,4 @@ caught sending USR2 sending USR2 +USR2 Index: shell/hush_leaktool.sh =================================================================== --- shell/hush_leaktool.sh (revision 26161) +++ shell/hush_leaktool.sh (revision 26162) @@ -6,8 +6,20 @@ freelist=`grep 'free 0x' "$output" | cut -d' ' -f2 | sort | uniq | xargs` grep -v free "$output" >"$output.leaked" + +i=8 +list= for freed in $freelist; do - echo Dropping $freed - grep -v $freed <"$output.leaked" >"$output.temp" + list="$list -e $freed" + test $((--i)) != 0 && continue + echo Dropping $list + grep -F -v $list <"$output.leaked" >"$output.temp" mv "$output.temp" "$output.leaked" + i=8 + list= done +if test "$list"; then + echo Dropping $list + grep -F -v $list <"$output.leaked" >"$output.temp" + mv "$output.temp" "$output.leaked" +fi ------------------------------------------------------------------------ r26161 | vda | 2009-04-19 16:37:07 -0500 (Sun, 19 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/testsuite/mdev.tests M /trunk/busybox/util-linux/mdev.c mdev: support $ENVVAR=regex ------------------------------------------------------------------------ Index: testsuite/mdev.tests =================================================================== --- testsuite/mdev.tests (revision 26160) +++ testsuite/mdev.tests (revision 26161) @@ -61,6 +61,19 @@ # continuing to use directory structure from prev test rm -rf mdev.testdir/dev/* +echo "\$MODALIAS=qw 1:1 666" >mdev.testdir/etc/mdev.conf +echo "\$MODALIAS=qw. 2:2 444" >>mdev.testdir/etc/mdev.conf +echo "\$MODALIAS=qw. 3:3 400" >>mdev.testdir/etc/mdev.conf +testing "mdev \$ENVVAR=regex match" \ + "env - PATH=$PATH ACTION=add DEVPATH=/block/sda MODALIAS=qwe chroot mdev.testdir /mdev 2>&1; + ls -ln mdev.testdir/dev | $FILTER_LS" \ +"\ +br--r--r-- 1 2 2 8,0 sda +" \ + "" "" + +# continuing to use directory structure from prev test +rm -rf mdev.testdir/dev/* echo "sda 0:0 444 >disk/scsiA" >mdev.testdir/etc/mdev.conf testing "mdev move/symlink rule '>bar/baz'" \ "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26160) +++ util-linux/mdev.c (revision 26161) @@ -89,15 +89,11 @@ /* NB: "mdev -s" may call us many times, do not leak memory/fds! */ static void make_device(char *path, int delete) { - const char *device_name; + char *device_name; int major, minor, type, len; int mode; - char *dev_maj_min = path + strlen(path); parser_t *parser; - /* Force the configuration file settings exactly. */ - umask(0); - /* Try to read major/minor string. Note that the kernel puts \n after * the data, so we don't need to worry about null terminating the string * because sscanf() will stop at the first nondigit, which \n is. @@ -105,21 +101,23 @@ */ major = -1; if (!delete) { + char *dev_maj_min = path + strlen(path); + strcpy(dev_maj_min, "/dev"); len = open_read_close(path, dev_maj_min + 1, 64); - *dev_maj_min++ = '\0'; + *dev_maj_min = '\0'; if (len < 1) { if (!ENABLE_FEATURE_MDEV_EXEC) return; - /* no "dev" file, so just try to run script */ - *dev_maj_min = '\0'; - } else if (sscanf(dev_maj_min, "%u:%u", &major, &minor) != 2) { + /* no "dev" file, but we can still run scripts + * based on device name */ + } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) != 2) { major = -1; } } /* Determine device name, type, major and minor */ - device_name = bb_basename(path); + device_name = (char*) bb_basename(path); /* http://kernel.org/doc/pending/hotplug.txt says that only * "/sys/block/..." is for block devices. "/sys/bus" etc is not. * But since 2.6.25 block devices are also in /sys/class/block, @@ -139,9 +137,7 @@ parser = config_open2("/etc/mdev.conf", fopen_for_read); do { - regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; int keep_matching; - char *val, *name; struct bb_uidgid_t ugid; char *tokens[4]; char *command = NULL; @@ -156,19 +152,22 @@ if (ENABLE_FEATURE_MDEV_CONF && config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL) ) { + char *val; + char *str_to_match; + regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; + val = tokens[0]; keep_matching = ('-' == val[0]); val += keep_matching; /* swallow leading dash */ /* Match against either "subsystem/device_name" * or "device_name" alone */ - name = strchr(val, '/') ? path : (char *) device_name; + str_to_match = strchr(val, '/') ? path : device_name; /* Fields: regex uid:gid mode [alias] [cmd] */ - /* 1st field: @ ... */ if (val[0] == '@') { - /* @major,minor[-last] */ + /* @major,minor[-minor2] */ /* (useful when name is ambiguous: * "/sys/class/usb/lp0" and * "/sys/class/printer/lp0") */ @@ -182,15 +181,29 @@ ) { continue; /* this line doesn't match */ } - } else { /* ... or regex to match device name */ + goto line_matches; + } + if (val[0] == '$') { + /* regex to match an environment variable */ + char *eq = strchr(++val, '='); + if (!eq) + continue; + *eq = '\0'; + str_to_match = getenv(val); + if (!str_to_match) + continue; + str_to_match -= strlen(val) + 1; + *eq = '='; + } + /* else: regex to match [subsystem/]device_name */ + + { regex_t match; int result; - /* Is this it? */ xregcomp(&match, val, REG_EXTENDED); - result = regexec(&match, name, ARRAY_SIZE(off), off, 0); + result = regexec(&match, str_to_match, ARRAY_SIZE(off), off, 0); regfree(&match); - //bb_error_msg("matches:"); //for (int i = 0; i < ARRAY_SIZE(off); i++) { // if (off[i].rm_so < 0) continue; @@ -199,18 +212,18 @@ // device_name + off[i].rm_so); //} - /* If not this device, skip rest of line */ + /* If no match, skip rest of line */ /* (regexec returns whole pattern as "range" 0) */ if (result || off[0].rm_so - || ((int)off[0].rm_eo != (int)strlen(name)) + || ((int)off[0].rm_eo != (int)strlen(str_to_match)) ) { continue; /* this line doesn't match */ } } + line_matches: + /* This line matches. Stop parsing after parsing + * the rest the line unless keep_matching == 1 */ - /* This line matches: stop parsing the file after parsing - * the rest of fields unless keep_matching == 1 */ - /* 2nd field: uid:gid - device ownership */ parse_chown_usergroup_or_die(&ugid, tokens[1]); @@ -243,7 +256,7 @@ if (*s++ == '%') n++; - p = alias = xzalloc(strlen(a) + n * strlen(name)); + p = alias = xzalloc(strlen(a) + n * strlen(str_to_match)); s = a + 1; while (*s) { *p = *s; @@ -251,7 +264,7 @@ i = (s[1] - '0'); if (i <= 9 && off[i].rm_so >= 0) { n = off[i].rm_eo - off[i].rm_so; - strncpy(p, name + off[i].rm_so, n); + strncpy(p, str_to_match + off[i].rm_so, n); p += n - 1; s++; } @@ -447,9 +460,11 @@ /* We can be called as hotplug helper */ /* Kernel cannot provide suitable stdio fds for us, do it ourself */ - bb_sanitize_stdio(); + /* Force the configuration file settings exactly */ + umask(0); + xchdir("/dev"); if (argv[1] && strcmp(argv[1], "-s") == 0) { ------------------------------------------------------------------------ r26160 | vda | 2009-04-19 09:12:50 -0500 (Sun, 19 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/applets/Kbuild another stab at fixing out-of-tree build ------------------------------------------------------------------------ Index: applets/Kbuild =================================================================== --- applets/Kbuild (revision 26159) +++ applets/Kbuild (revision 26160) @@ -16,7 +16,7 @@ # This trick decreases amount of rebuilds # if tree is merely renamed/copied -ifeq ($(src),$(obj)) +ifeq ($(srctree),$(objtree)) srctree_slash = else srctree_slash = $(srctree)/ ------------------------------------------------------------------------ r26159 | vda | 2009-04-19 09:03:11 -0500 (Sun, 19 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c same as previous, but -100 bytes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26158) +++ shell/hush.c (revision 26159) @@ -5476,22 +5476,24 @@ * will still trigger for us */ } } + + /* "cmd}" or "cmd }..." without semicolon or &: + * } is an ordinary char in this case, even inside { cmd; } + * Pathological example: { ""}; } should exec "}" cmd + */ + if (ch == '}' + && !(IS_NULL_PIPE(ctx.pipe) + && IS_NULL_CMD(ctx.command) + && dest.length == 0 + && !dest.o_quoted + ) + ) { + goto ordinary_char; + } + if (end_trigger && end_trigger == ch && (heredoc_cnt == 0 || end_trigger != ';') ) { - /* "{ cmd}" or "{ cmd }..." without semicolon or &: - * } is an ordinary char in this case. - * Pathological example: { ""}; } should exec "}" cmd - */ - if (ch == '}' - && !(IS_NULL_PIPE(ctx.pipe) - && IS_NULL_CMD(ctx.command) - && dest.length == 0 - && !dest.o_quoted - ) - ) { - goto ordinary_char; - } if (heredoc_cnt) { /* This is technically valid: * { cat < ------------------------------------------------------------------------ r26158 | vda | 2009-04-19 08:57:51 -0500 (Sun, 19 Apr 2009) | 7 lines Changed paths: M /trunk/busybox/shell/hush.c M /trunk/busybox/shell/hush_test/hush-misc/export.right A /trunk/busybox/shell/hush_test/hush-parsing/group1.right A /trunk/busybox/shell/hush_test/hush-parsing/group1.tests M /trunk/busybox/shell/hush_test/hush-vars/var_posix1.right M /trunk/busybox/shell/hush_test/hush-vars/var_posix1.tests hush: fix handling of } which is not a closing one in { cmd; } function old new delta parse_stream 2176 2302 +126 builtin_unset 381 387 +6 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26157) +++ shell/hush.c (revision 26158) @@ -1822,7 +1822,7 @@ goto literal; } if (gr != 0) { /* GLOB_ABORTED ? */ -//TODO: testcase for bad glob pattern behavior + /* TODO: testcase for bad glob pattern behavior */ bb_error_msg("glob(3) error %d on '%s'", gr, pattern); } if (globdata.gl_pathv && globdata.gl_pathv[0]) { @@ -2339,7 +2339,8 @@ if (HUSH_DEBUG) if (list[n-1] + strlen(list[n-1]) + 1 != list[n]) bb_error_msg_and_die("BUG in varexp3"); - list[n][-1] = ' '; /* TODO: or to G.ifs[0]? */ + /* bash uses ' ' regardless of $IFS contents */ + list[n][-1] = ' '; n++; } } @@ -5128,14 +5129,16 @@ while (1) { ch = i_getch(input); nommu_addchr(as_string, ch); - if (ch == '}') + if (ch == '}') { break; + } if (first_char) { - if (ch == '#') + if (ch == '#') { /* ${#var}: length of var contents */ goto char_ok; - else if (isdigit(ch)) { + } + if (isdigit(ch)) { all_digits = true; goto char_ok; } @@ -5186,7 +5189,7 @@ o_addchr(dest, ch | quote_mask); quote_mask = 0; first_char = false; - } + } /* while (1) */ o_addchr(dest, SPECIAL_VAR_SYMBOL); break; } @@ -5432,6 +5435,7 @@ , ch); if (!is_special && !is_ifs) { /* ordinary char */ + ordinary_char: o_addQchr(&dest, ch); if ((dest.o_assignment == MAYBE_ASSIGNMENT || dest.o_assignment == WORD_IS_KEYWORD) @@ -5475,6 +5479,19 @@ if (end_trigger && end_trigger == ch && (heredoc_cnt == 0 || end_trigger != ';') ) { + /* "{ cmd}" or "{ cmd }..." without semicolon or &: + * } is an ordinary char in this case. + * Pathological example: { ""}; } should exec "}" cmd + */ + if (ch == '}' + && !(IS_NULL_PIPE(ctx.pipe) + && IS_NULL_CMD(ctx.command) + && dest.length == 0 + && !dest.o_quoted + ) + ) { + goto ordinary_char; + } if (heredoc_cnt) { /* This is technically valid: * { cat < ------------------------------------------------------------------------ r26157 | vda | 2009-04-19 07:15:51 -0500 (Sun, 19 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/applets/Kbuild hopefully fix out-of-tree build broken by 26139 ------------------------------------------------------------------------ Index: applets/Kbuild =================================================================== --- applets/Kbuild (revision 26156) +++ applets/Kbuild (revision 26157) @@ -13,21 +13,27 @@ always:= $(hostprogs-y) # Generated files need additional love -# NB: __srctree is either empty or "srctree/" -# using it instead of srctree decreases amount of rebuilds + +# This trick decreases amount of rebuilds # if tree is merely renamed/copied +ifeq ($(src),$(obj)) +srctree_slash = +else +srctree_slash = $(srctree)/ +endif -HOSTCFLAGS_usage.o = -I$(__srctree)include +HOSTCFLAGS_usage.o = -I$(srctree_slash)include + applets/applets.o: include/usage_compressed.h include/applet_tables.h -applets/usage: .config $(__srctree)applets/usage_compressed +applets/usage: .config $(srctree_slash)applets/usage_compressed applets/applet_tables: .config quiet_cmd_gen_usage_compressed = GEN include/usage_compressed.h - cmd_gen_usage_compressed = $(__srctree)applets/usage_compressed include/usage_compressed.h applets + cmd_gen_usage_compressed = $(srctree_slash)applets/usage_compressed include/usage_compressed.h applets -include/usage_compressed.h: applets/usage $(__srctree)applets/usage_compressed +include/usage_compressed.h: applets/usage $(srctree_slash)applets/usage_compressed $(call cmd,gen_usage_compressed) quiet_cmd_gen_applet_tables = GEN include/applet_tables.h ------------------------------------------------------------------------ r26156 | vda | 2009-04-18 20:27:20 -0500 (Sat, 18 Apr 2009) | 4 lines Changed paths: M /trunk/busybox/coreutils/stty.c M /trunk/busybox/editors/awk.c M /trunk/busybox/libbb/parse_config.c M /trunk/busybox/networking/libiproute/ll_map.c M /trunk/busybox/networking/libiproute/ll_map.h M /trunk/busybox/selinux/setfiles.c M /trunk/busybox/util-linux/mdev.c mdev: Rob's #if forest removal *: remove superfluous conts in "f(type *const param)" ------------------------------------------------------------------------ Index: networking/libiproute/ll_map.c =================================================================== --- networking/libiproute/ll_map.c (revision 26155) +++ networking/libiproute/ll_map.c (revision 26156) @@ -133,7 +133,7 @@ return 0; } -int xll_name_to_index(const char *const name) +int xll_name_to_index(const char *name) { int ret = 0; int sock_fd; Index: networking/libiproute/ll_map.h =================================================================== --- networking/libiproute/ll_map.h (revision 26155) +++ networking/libiproute/ll_map.h (revision 26156) @@ -6,7 +6,7 @@ int ll_remember_index(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); int ll_init_map(struct rtnl_handle *rth); -int xll_name_to_index(const char *const name); +int xll_name_to_index(const char *name); const char *ll_index_to_name(int idx); const char *ll_idx_n2a(int idx, char *buf); /* int ll_index_to_type(int idx); */ Index: coreutils/stty.c =================================================================== --- coreutils/stty.c (revision 26155) +++ coreutils/stty.c (revision 26156) @@ -677,8 +677,8 @@ return NULL; } -static void set_speed_or_die(enum speed_setting type, const char *const arg, - struct termios * const mode) +static void set_speed_or_die(enum speed_setting type, const char *arg, + struct termios *mode) { speed_t baud; @@ -801,7 +801,7 @@ param_ospeed = 8 | 0x80, }; -static int find_param(const char *const name) +static int find_param(const char *name) { static const char params[] ALIGN1 = "line\0" /* 1 */ Index: libbb/parse_config.c =================================================================== --- libbb/parse_config.c (revision 26155) +++ libbb/parse_config.c (revision 26156) @@ -79,7 +79,7 @@ return config_open2(filename, fopen_or_warn_stdin); } -static void config_free_data(parser_t *const parser) +static void config_free_data(parser_t *parser) { free(parser->line); parser->line = NULL; Index: selinux/setfiles.c =================================================================== --- selinux/setfiles.c (revision 26155) +++ selinux/setfiles.c (revision 26156) @@ -112,7 +112,7 @@ } } -static void add_exclude(const char *const directory) +static void add_exclude(const char *directory) { struct stat sb; size_t len; Index: editors/awk.c =================================================================== --- editors/awk.c (revision 26155) +++ editors/awk.c (revision 26156) @@ -521,8 +521,8 @@ memset(vp, 0, sizeof(*vp)); } -static void syntax_error(const char *const message) NORETURN; -static void syntax_error(const char *const message) +static void syntax_error(const char *message) NORETURN; +static void syntax_error(const char *message) { bb_error_msg_and_die("%s:%i: %s", g_progname, g_lineno, message); } Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26155) +++ util-linux/mdev.c (revision 26156) @@ -52,7 +52,7 @@ #define G (*(struct globals*)&bb_common_bufsiz1) #define root_major (G.root_major) #define root_minor (G.root_minor) -#define subsystem (G.subsystem) +#define subsystem (G.subsystem ) /* Prevent infinite loops in /sys symlinks */ #define MAX_SYSFS_DEPTH 3 @@ -60,9 +60,9 @@ /* We use additional 64+ bytes in make_device() */ #define SCRATCH_SIZE 80 -#if ENABLE_FEATURE_MDEV_RENAME /* Builds an alias path. * This function potentionally reallocates the alias parameter. + * Only used for ENABLE_FEATURE_MDEV_RENAME */ static char *build_alias(char *alias, const char *device_name) { @@ -84,19 +84,16 @@ return alias; } -#endif /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ /* NB: "mdev -s" may call us many times, do not leak memory/fds! */ static void make_device(char *path, int delete) { -#if ENABLE_FEATURE_MDEV_CONF - parser_t *parser; -#endif const char *device_name; int major, minor, type, len; int mode; char *dev_maj_min = path + strlen(path); + parser_t *parser; /* Force the configuration file settings exactly. */ umask(0); @@ -137,170 +134,153 @@ else path += sizeof("/sys/class/") - 1; -#if !ENABLE_FEATURE_MDEV_CONF - mode = 0660; -#else /* If we have config file, look up user settings */ - parser = config_open2("/etc/mdev.conf", fopen_for_read); - while (1) { + if (ENABLE_FEATURE_MDEV_CONF) + parser = config_open2("/etc/mdev.conf", fopen_for_read); + + do { regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; int keep_matching; char *val, *name; struct bb_uidgid_t ugid; char *tokens[4]; -# if ENABLE_FEATURE_MDEV_EXEC char *command = NULL; -# endif -# if ENABLE_FEATURE_MDEV_RENAME char *alias = NULL; char aliaslink = aliaslink; /* for compiler */ -# endif + /* Defaults in case we won't match any line */ ugid.uid = ugid.gid = 0; keep_matching = 0; mode = 0660; - if (!config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL)) { - /* End of file, create dev node with default params */ - goto line_matches; - } + if (ENABLE_FEATURE_MDEV_CONF + && config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL) + ) { + val = tokens[0]; + keep_matching = ('-' == val[0]); + val += keep_matching; /* swallow leading dash */ - val = tokens[0]; - keep_matching = ('-' == val[0]); - val += keep_matching; /* swallow leading dash */ + /* Match against either "subsystem/device_name" + * or "device_name" alone */ + name = strchr(val, '/') ? path : (char *) device_name; - /* Match against either "subsystem/device_name" - * or "device_name" alone */ - name = strchr(val, '/') ? path : (char *) device_name; + /* Fields: regex uid:gid mode [alias] [cmd] */ - /* Fields: regex uid:gid mode [alias] [cmd] */ + /* 1st field: @ ... */ + if (val[0] == '@') { + /* @major,minor[-last] */ + /* (useful when name is ambiguous: + * "/sys/class/usb/lp0" and + * "/sys/class/printer/lp0") */ + int cmaj, cmin0, cmin1, sc; + if (major < 0) + continue; /* no dev, no match */ + sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1); + if (sc < 1 || major != cmaj + || (sc == 2 && minor != cmin0) + || (sc == 3 && (minor < cmin0 || minor > cmin1)) + ) { + continue; /* this line doesn't match */ + } + } else { /* ... or regex to match device name */ + regex_t match; + int result; - /* 1st field: @ ... */ - if (val[0] == '@') { - /* @major,minor[-last] */ - /* (useful when name is ambiguous: - * "/sys/class/usb/lp0" and - * "/sys/class/printer/lp0") */ - int cmaj, cmin0, cmin1, sc; - if (major < 0) - continue; /* no dev, no match */ - sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1); - if (sc < 1 || major != cmaj - || (sc == 2 && minor != cmin0) - || (sc == 3 && (minor < cmin0 || minor > cmin1)) - ) { - continue; /* this line doesn't match */ - } - } else { /* ... or regex to match device name */ - regex_t match; - int result; + /* Is this it? */ + xregcomp(&match, val, REG_EXTENDED); + result = regexec(&match, name, ARRAY_SIZE(off), off, 0); + regfree(&match); - /* Is this it? */ - xregcomp(&match, val, REG_EXTENDED); - result = regexec(&match, name, ARRAY_SIZE(off), off, 0); - regfree(&match); + //bb_error_msg("matches:"); + //for (int i = 0; i < ARRAY_SIZE(off); i++) { + // if (off[i].rm_so < 0) continue; + // bb_error_msg("match %d: '%.*s'\n", i, + // (int)(off[i].rm_eo - off[i].rm_so), + // device_name + off[i].rm_so); + //} - //bb_error_msg("matches:"); - //for (int i = 0; i < ARRAY_SIZE(off); i++) { - // if (off[i].rm_so < 0) continue; - // bb_error_msg("match %d: '%.*s'\n", i, - // (int)(off[i].rm_eo - off[i].rm_so), - // device_name + off[i].rm_so); - //} - - /* If not this device, skip rest of line */ - /* (regexec returns whole pattern as "range" 0) */ - if (result || off[0].rm_so - || ((int)off[0].rm_eo != (int)strlen(name)) - ) { - continue; /* this line doesn't match */ + /* If not this device, skip rest of line */ + /* (regexec returns whole pattern as "range" 0) */ + if (result || off[0].rm_so + || ((int)off[0].rm_eo != (int)strlen(name)) + ) { + continue; /* this line doesn't match */ + } } - } - /* This line matches: stop parsing the file after parsing - * the rest of fields unless keep_matching == 1 */ + /* This line matches: stop parsing the file after parsing + * the rest of fields unless keep_matching == 1 */ - /* 2nd field: uid:gid - device ownership */ - parse_chown_usergroup_or_die(&ugid, tokens[1]); + /* 2nd field: uid:gid - device ownership */ + parse_chown_usergroup_or_die(&ugid, tokens[1]); - /* 3rd field: mode - device permissions */ - mode = strtoul(tokens[2], NULL, 8); + /* 3rd field: mode - device permissions */ + mode = strtoul(tokens[2], NULL, 8); - val = tokens[3]; - /* 4th field (opt): >|=alias */ -# if ENABLE_FEATURE_MDEV_RENAME - if (!val) - goto line_matches; - aliaslink = val[0]; - if (aliaslink == '>' || aliaslink == '=') { - char *a, *s, *st; -# if ENABLE_FEATURE_MDEV_RENAME_REGEXP - char *p; - unsigned i, n; -# endif - a = val; - s = strchrnul(val, ' '); - st = strchrnul(val, '\t'); - if (st < s) - s = st; - val = (s[0] && s[1]) ? s+1 : NULL; - s[0] = '\0'; + val = tokens[3]; + /* 4th field (opt): >|=alias */ -# if ENABLE_FEATURE_MDEV_RENAME_REGEXP - /* substitute %1..9 with off[1..9], if any */ - n = 0; - s = a; - while (*s) - if (*s++ == '%') - n++; + if (ENABLE_FEATURE_MDEV_RENAME && val) { + aliaslink = val[0]; + if (aliaslink == '>' || aliaslink == '=') { + char *a, *s, *st; + char *p; + unsigned i, n; - p = alias = xzalloc(strlen(a) + n * strlen(name)); - s = a + 1; - while (*s) { - *p = *s; - if ('%' == *s) { - i = (s[1] - '0'); - if (i <= 9 && off[i].rm_so >= 0) { - n = off[i].rm_eo - off[i].rm_so; - strncpy(p, name + off[i].rm_so, n); - p += n - 1; - s++; + a = val; + s = strchrnul(val, ' '); + st = strchrnul(val, '\t'); + if (st < s) + s = st; + val = (s[0] && s[1]) ? s+1 : NULL; + s[0] = '\0'; + + if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { + /* substitute %1..9 with off[1..9], if any */ + n = 0; + s = a; + while (*s) + if (*s++ == '%') + n++; + + p = alias = xzalloc(strlen(a) + n * strlen(name)); + s = a + 1; + while (*s) { + *p = *s; + if ('%' == *s) { + i = (s[1] - '0'); + if (i <= 9 && off[i].rm_so >= 0) { + n = off[i].rm_eo - off[i].rm_so; + strncpy(p, name + off[i].rm_so, n); + p += n - 1; + s++; + } + } + p++; + s++; + } + } else { + alias = xstrdup(a + 1); } } - p++; - s++; } -# else - alias = xstrdup(a + 1); -# endif - } -# endif /* ENABLE_FEATURE_MDEV_RENAME */ -# if ENABLE_FEATURE_MDEV_EXEC - /* The rest (opt): @|$|*command */ - if (!val) - goto line_matches; - { - const char *s = "@$*"; - const char *s2 = strchr(s, val[0]); + if (ENABLE_FEATURE_MDEV_EXEC && val) { + const char *s = "$@*"; + const char *s2 = strchr(s, val[0]); - if (!s2) - bb_error_msg_and_die("bad line %u", parser->lineno); + if (!s2) + bb_error_msg_and_die("bad line %u", parser->lineno); - /* Correlate the position in the "@$*" with the delete - * step so that we get the proper behavior: - * @cmd: run on create - * $cmd: run on delete - * *cmd: run on both - */ - if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) { - command = xstrdup(val + 1); + /* Are we running this command now? + * Run $cmd on delete, @cmd on create, *cmd on both + */ + if (s2-s != delete) + command = xstrdup(val + 1); } } -# endif + /* End of field parsing */ - line_matches: -#endif /* ENABLE_FEATURE_MDEV_CONF */ /* "Execute" the line we found */ @@ -311,11 +291,11 @@ bb_perror_msg_and_die("mknod %s", device_name); if (major == root_major && minor == root_minor) symlink(device_name, "root"); -#if ENABLE_FEATURE_MDEV_CONF - chmod(device_name, mode); - chown(device_name, ugid.uid, ugid.gid); -# if ENABLE_FEATURE_MDEV_RENAME - if (alias) { + if (ENABLE_FEATURE_MDEV_CONF) { + chmod(device_name, mode); + chown(device_name, ugid.uid, ugid.gid); + } + if (ENABLE_FEATURE_MDEV_RENAME && alias) { alias = build_alias(alias, device_name); /* move the device, and optionally * make a symlink to moved device node */ @@ -323,11 +303,9 @@ symlink(alias, device_name); free(alias); } -# endif -#endif } -#if ENABLE_FEATURE_MDEV_EXEC - if (command) { + + if (ENABLE_FEATURE_MDEV_EXEC && command) { /* setenv will leak memory, use putenv/unsetenv/free */ char *s = xasprintf("%s=%s", "MDEV", device_name); char *s1 = xasprintf("%s=%s", "SUBSYSTEM", subsystem); @@ -341,29 +319,29 @@ free(s); free(command); } -#endif + if (delete) { unlink(device_name); /* At creation time, device might have been moved * and a symlink might have been created. Undo that. */ -#if ENABLE_FEATURE_MDEV_RENAME - if (alias) { + + if (ENABLE_FEATURE_MDEV_RENAME && alias) { alias = build_alias(alias, device_name); unlink(alias); free(alias); } -#endif } -#if ENABLE_FEATURE_MDEV_CONF /* We found matching line. * Stop unless it was prefixed with '-' */ - if (!keep_matching) + if (ENABLE_FEATURE_MDEV_CONF && !keep_matching) break; - } /* end of "while line is read from /etc/mdev.conf" */ - config_close(parser); -#endif /* ENABLE_FEATURE_MDEV_CONF */ + /* end of "while line is read from /etc/mdev.conf" */ + } while (ENABLE_FEATURE_MDEV_CONF); + + if (ENABLE_FEATURE_MDEV_CONF) + config_close(parser); } /* File callback for /sys/ traversal */ @@ -415,7 +393,7 @@ * - userspace writes "0" (worked) or "-1" (failed) to /sys/$DEVPATH/loading * - kernel loads firmware into device */ -static void load_firmware(const char *const firmware, const char *const sysfs_path) +static void load_firmware(const char *firmware, const char *sysfs_path) { int cnt; int firmware_fd, loading_fd, data_fd; @@ -469,18 +447,8 @@ /* We can be called as hotplug helper */ /* Kernel cannot provide suitable stdio fds for us, do it ourself */ -#if 1 + bb_sanitize_stdio(); -#else - /* Debug code */ - /* Replace LOGFILE by other file or device name if you need */ -#define LOGFILE "/dev/console" - /* Just making sure fd 0 is not closed, - * we don't really intend to read from it */ - xmove_fd(xopen("/", O_RDONLY), STDIN_FILENO); - xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDOUT_FILENO); - xmove_fd(xopen(LOGFILE, O_WRONLY|O_APPEND), STDERR_FILENO); -#endif xchdir("/dev"); ------------------------------------------------------------------------ r26152 | vapier | 2009-04-18 16:04:25 -0500 (Sat, 18 Apr 2009) | 1 line Changed paths: M /trunk/busybox/shell/hush.c fix build errors when function support is turned off ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26151) +++ shell/hush.c (revision 26152) @@ -2901,13 +2901,17 @@ static int run_function(const struct function *funcp, char **argv) { int rc; + save_arg_t sv; +#if ENABLE_HUSH_FUNCTIONS smallint sv_flg; - save_arg_t sv; +#endif save_and_replace_G_args(&sv, argv); +#if ENABLE_HUSH_FUNCTIONS /* "we are in function, ok to use return" */ sv_flg = G.flag_return_in_progress; G.flag_return_in_progress = -1; +#endif /* On MMU, funcp->body is always non-NULL */ #if !BB_MMU @@ -2921,7 +2925,9 @@ rc = run_list(funcp->body); } +#if ENABLE_HUSH_FUNCTIONS G.flag_return_in_progress = sv_flg; +#endif restore_G_args(&sv, argv); return rc; @@ -6775,8 +6781,10 @@ static int builtin_source(char **argv) { FILE *input; + save_arg_t sv; +#if ENABLE_HUSH_FUNCTIONS smallint sv_flg; - save_arg_t sv; +#endif if (*++argv == NULL) return EXIT_FAILURE; @@ -6789,16 +6797,20 @@ } close_on_exec_on(fileno(input)); +#if ENABLE_HUSH_FUNCTIONS sv_flg = G.flag_return_in_progress; /* "we are inside sourced file, ok to use return" */ G.flag_return_in_progress = -1; +#endif save_and_replace_G_args(&sv, argv); parse_and_run_file(input); fclose(input); restore_G_args(&sv, argv); +#if ENABLE_HUSH_FUNCTIONS G.flag_return_in_progress = sv_flg; +#endif return G.last_exitcode; } ------------------------------------------------------------------------ r26149 | vda | 2009-04-18 08:05:10 -0500 (Sat, 18 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: fix thinko in error msg ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26148) +++ shell/hush.c (revision 26149) @@ -6430,7 +6430,6 @@ static int builtin_trap(char **argv) { - int i; int sig; char *new_cmd; @@ -6439,6 +6438,7 @@ argv++; if (!*argv) { + int i; /* No args: print all trapped */ for (i = 0; i < NSIG; ++i) { if (G.traps[i]) { @@ -6452,7 +6452,6 @@ } new_cmd = NULL; - i = 0; /* If first arg is a number: reset all specified signals */ sig = bb_strtou(*argv, NULL, 10); if (errno == 0) { @@ -6464,7 +6463,7 @@ if (sig < 0 || sig >= NSIG) { ret = EXIT_FAILURE; /* Mimic bash message exactly */ - bb_perror_msg("trap: %s: invalid signal specification", argv[i]); + bb_perror_msg("trap: %s: invalid signal specification", argv[-1]); continue; } @@ -6488,8 +6487,8 @@ continue; sigdelset(&G.blocked_set, sig); } - sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); } + sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); return ret; } ------------------------------------------------------------------------ r26148 | vda | 2009-04-18 07:58:19 -0500 (Sat, 18 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: fix "trap -- handler SIGs..."; escape handlers in "trap" output ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26147) +++ shell/hush.c (revision 26148) @@ -3246,14 +3246,16 @@ fg_pipe->alive_cmds--; if (i == fg_pipe->num_cmds - 1) { /* last process gives overall exitstatus */ + /* Note: is WIFSIGNALED, WEXITSTATUS = sig + 128 */ rcode = WEXITSTATUS(status); IF_HAS_KEYWORDS(if (fg_pipe->pi_inverted) rcode = !rcode;) /* bash prints killing signal's name for *last* * process in pipe (prints just newline for SIGINT). - * we just print newline for any sig: + * Mimic this. Example: "sleep 5" + ^\ */ if (WIFSIGNALED(status)) { - bb_putchar('\n'); + int sig = WTERMSIG(status); + printf("%s\n", sig == SIGINT ? "" : get_signame(sig)); } } } else { @@ -3489,6 +3491,7 @@ debug_printf_exec(": builtin '%s' '%s'...\n", x->cmd, argv_expanded[1]); rcode = x->function(argv_expanded) & 0xff; + fflush(NULL); } #if ENABLE_HUSH_FUNCTIONS else { @@ -6251,81 +6254,6 @@ /* * Built-ins */ -static int builtin_trap(char **argv) -{ - int i; - int sig; - char *new_cmd; - - if (!G.traps) - G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); - - argv++; - if (!*argv) { - /* No args: print all trapped. This isn't 100% correct as we - * should be escaping the cmd so that it can be pasted back in - */ - for (i = 0; i < NSIG; ++i) - if (G.traps[i]) - printf("trap -- '%s' %s\n", G.traps[i], get_signame(i)); - return EXIT_SUCCESS; - } - - new_cmd = NULL; - i = 0; - /* If first arg is decimal: reset all specified signals */ - sig = bb_strtou(*argv, NULL, 10); - if (errno == 0) { - int ret; - set_all: - ret = EXIT_SUCCESS; - while (*argv) { - sig = get_signum(*argv++); - if (sig < 0 || sig >= NSIG) { - ret = EXIT_FAILURE; - /* Mimic bash message exactly */ - bb_perror_msg("trap: %s: invalid signal specification", argv[i]); - continue; - } - - free(G.traps[sig]); - G.traps[sig] = xstrdup(new_cmd); - - debug_printf("trap: setting SIG%s (%i) to '%s'", - get_signame(sig), sig, G.traps[sig]); - - /* There is no signal for 0 (EXIT) */ - if (sig == 0) - continue; - - if (new_cmd) { - sigaddset(&G.blocked_set, sig); - } else { - /* There was a trap handler, we are removing it - * (if sig has non-DFL handling, - * we don't need to do anything) */ - if (sig < 32 && (G.non_DFL_mask & (1 << sig))) - continue; - sigdelset(&G.blocked_set, sig); - } - sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); - } - return ret; - } - - /* First arg is "-": reset all specified to default */ - /* First arg is "": ignore all specified */ - /* Everything else: execute first arg upon signal */ - if (!argv[1]) { - bb_error_msg("trap: invalid arguments"); - return EXIT_FAILURE; - } - if (NOT_LONE_DASH(*argv)) - new_cmd = *argv; - argv++; - goto set_all; -} - static int builtin_true(char **argv UNUSED_PARAM) { return 0; @@ -6427,6 +6355,26 @@ hush_exit(xatoi(*argv) & 0xff); } +static void print_escaped(const char *s) +{ + do { + if (*s != '\'') { + const char *p; + + p = strchrnul(s, '\''); + /* print 'xxxx', possibly just '' */ + printf("'%.*s'", (int)(p - s), s); + if (*p == '\0') + break; + s = p; + } + /* s points to '; print "'''...'''" */ + putchar('"'); + do putchar('\''); while (*++s == '\''); + putchar('"'); + } while (*s); +} + static int builtin_export(char **argv) { if (*++argv == NULL) { @@ -6446,25 +6394,11 @@ continue; /* export var= */ printf("export %.*s", (int)(p - s) + 1, s); - s = p + 1; - while (*s) { - if (*s != '\'') { - p = strchrnul(s, '\''); - /* print 'xxxx' */ - printf("'%.*s'", (int)(p - s), s); - if (*p == '\0') - break; - s = p; - } - /* s points to '; print ''...'''" */ - putchar('"'); - do putchar('\''); while (*++s == '\''); - putchar('"'); - } + print_escaped(p + 1); putchar('\n'); #endif } - fflush(stdout); + /*fflush(stdout); - done after each builtin anyway */ } return EXIT_SUCCESS; } @@ -6494,6 +6428,96 @@ return EXIT_SUCCESS; } +static int builtin_trap(char **argv) +{ + int i; + int sig; + char *new_cmd; + + if (!G.traps) + G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); + + argv++; + if (!*argv) { + /* No args: print all trapped */ + for (i = 0; i < NSIG; ++i) { + if (G.traps[i]) { + printf("trap -- "); + print_escaped(G.traps[i]); + printf(" %s\n", get_signame(i)); + } + } + /*fflush(stdout); - done after each builtin anyway */ + return EXIT_SUCCESS; + } + + new_cmd = NULL; + i = 0; + /* If first arg is a number: reset all specified signals */ + sig = bb_strtou(*argv, NULL, 10); + if (errno == 0) { + int ret; + process_sig_list: + ret = EXIT_SUCCESS; + while (*argv) { + sig = get_signum(*argv++); + if (sig < 0 || sig >= NSIG) { + ret = EXIT_FAILURE; + /* Mimic bash message exactly */ + bb_perror_msg("trap: %s: invalid signal specification", argv[i]); + continue; + } + + free(G.traps[sig]); + G.traps[sig] = xstrdup(new_cmd); + + debug_printf("trap: setting SIG%s (%i) to '%s'", + get_signame(sig), sig, G.traps[sig]); + + /* There is no signal for 0 (EXIT) */ + if (sig == 0) + continue; + + if (new_cmd) { + sigaddset(&G.blocked_set, sig); + } else { + /* There was a trap handler, we are removing it + * (if sig has non-DFL handling, + * we don't need to do anything) */ + if (sig < 32 && (G.non_DFL_mask & (1 << sig))) + continue; + sigdelset(&G.blocked_set, sig); + } + sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); + } + return ret; + } + + if (!argv[1]) { /* no second arg */ + bb_error_msg("trap: invalid arguments"); + return EXIT_FAILURE; + } + + /* First arg is "-": reset all specified to default */ + /* First arg is "--": skip it, the rest is "handler SIGs..." */ + /* Everything else: set arg as signal handler + * (includes "" case, which ignores signal) */ + if (argv[0][0] == '-') { + if (argv[0][1] == '\0') { /* "-" */ + /* new_cmd remains NULL: "reset these sigs" */ + goto reset_traps; + } + if (argv[0][1] == '-' && argv[0][2] == '\0') { /* "--" */ + argv++; + } + /* else: "-something", no special meaning */ + } + new_cmd = *argv; + reset_traps: + argv++; + goto process_sig_list; +} + #if ENABLE_HUSH_JOB /* built-in 'fg' and 'bg' handler */ static int builtin_fg_bg(char **argv) ------------------------------------------------------------------------ r26147 | vda | 2009-04-18 06:35:16 -0500 (Sat, 18 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/acpid.c acpid: prevent creation of zombies ------------------------------------------------------------------------ Index: util-linux/acpid.c =================================================================== --- util-linux/acpid.c (revision 26146) +++ util-linux/acpid.c (revision 26147) @@ -78,8 +78,8 @@ // goto configuration directory xchdir(opt_conf); -// // setup signals -// bb_signals(BB_FATAL_SIGS, record_signo); + // prevent zombies + signal(SIGCHLD, SIG_IGN); // no explicit evdev files given? -> use proc event interface if (!*argv) { ------------------------------------------------------------------------ r26146 | vda | 2009-04-18 06:25:18 -0500 (Sat, 18 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: fix thinko in unset_func ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26145) +++ shell/hush.c (revision 26146) @@ -2863,6 +2863,7 @@ free(funcp); break; } + funcpp = &funcp->next; } } ------------------------------------------------------------------------ r26145 | vda | 2009-04-18 06:23:38 -0500 (Sat, 18 Apr 2009) | 9 lines Changed paths: M /trunk/busybox/shell/hush.c hush: implement unset -f; beautify the handling of signal-killed pipe four TODOs are gone function old new delta builtin_unset 271 364 +93 checkjobs 394 428 +34 builtin_exit 49 47 -2 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26144) +++ shell/hush.c (revision 26145) @@ -1185,7 +1185,6 @@ // G.count_SIGCHLD++; // break; case SIGINT: -//TODO: add putchar('\n') also when we detect that child was killed (sleep 5 + ^C) /* Builtin was ^C'ed, make it look prettier: */ bb_putchar('\n'); G.flag_SIGINT = 1; @@ -2842,6 +2841,31 @@ return funcp; } +static void unset_func(const char *name) +{ + struct function *funcp; + struct function **funcpp = &G.top_func; + + while ((funcp = *funcpp) != NULL) { + if (strcmp(funcp->name, name) == 0) { + *funcpp = funcp->next; + /* funcp is unlinked now, deleting it */ + free(funcp->name); + /* Note: if !funcp->body, do not free body_as_string! + * This is a special case of "-F name body" function: + * body_as_string was not malloced! */ + if (funcp->body) { + free_pipe_list(funcp->body); +#if !BB_MMU + free(funcp->body_as_string); +#endif + } + free(funcp); + break; + } + } +} + #if BB_MMU #define exec_function(nommu_save, funcp, argv) \ exec_function(funcp, argv) @@ -3223,6 +3247,13 @@ /* last process gives overall exitstatus */ rcode = WEXITSTATUS(status); IF_HAS_KEYWORDS(if (fg_pipe->pi_inverted) rcode = !rcode;) + /* bash prints killing signal's name for *last* + * process in pipe (prints just newline for SIGINT). + * we just print newline for any sig: + */ + if (WIFSIGNALED(status)) { + bb_putchar('\n'); + } } } else { fg_pipe->cmds[i].is_stopped = 1; @@ -6372,12 +6403,20 @@ static int builtin_exit(char **argv) { debug_printf_exec("%s()\n", __func__); -// TODO: bash does it ONLY on top-level sh exit (+interacive only?) - //puts("exit"); /* bash does it */ -// TODO: warn if we have background jobs: "There are stopped jobs" -// On second consecutive 'exit', exit anyway. -// perhaps use G.exiting = -1 as indicator "last cmd was exit" + /* interactive bash: + * # trap "echo EEE" EXIT + * # exit + * exit + * There are stopped jobs. + * (if there are _stopped_ jobs, running ones don't count) + * # exit + * exit + # EEE (then bash exits) + * + * we can use G.exiting = -1 as indicator "last cmd was exit" + */ + /* note: EXIT trap is run by hush_exit */ if (*++argv == NULL) hush_exit(G.last_exitcode); @@ -6776,28 +6815,34 @@ { int ret; char var; + char *arg; if (!*++argv) return EXIT_SUCCESS; - var = 'v'; - if (argv[0][0] == '-') { - switch (argv[0][1]) { - case 'v': - case 'f': - var = argv[0][1]; - break; - default: - bb_error_msg("unset: %s: invalid option", *argv); - return EXIT_FAILURE; + var = 0; + while ((arg = *argv) != NULL && arg[0] == '-') { + while (*++arg) { + switch (*arg) { + case 'v': + case 'f': + if (var == 0 || var == *arg) { + var = *arg; + break; + } + /* else: unset -vf, which is illegal. + * fall through */ + default: + bb_error_msg("unset: %s: invalid option", *argv); + return EXIT_FAILURE; + } } -//TODO: disallow "unset -vf ..." too argv++; } ret = EXIT_SUCCESS; while (*argv) { - if (var == 'v') { + if (var != 'f') { if (unset_local_var(*argv)) { /* unset doesn't fail. * Error is when one tries to unset RO var. @@ -6805,11 +6850,11 @@ ret = EXIT_FAILURE; } } -//#if ENABLE_HUSH_FUNCTIONS -// else { -// unset_local_func(*argv); -// } -//#endif +#if ENABLE_HUSH_FUNCTIONS + else { + unset_func(*argv); + } +#endif argv++; } return ret; ------------------------------------------------------------------------ r26144 | vda | 2009-04-17 21:06:54 -0500 (Fri, 17 Apr 2009) | 6 lines Changed paths: M /trunk/busybox/shell/ash.c M /trunk/busybox/shell/hush.c hush: deal with umask TODO (symbolic modes) function old new delta builtin_umask 79 125 +46 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26143) +++ shell/hush.c (revision 26144) @@ -6742,24 +6742,33 @@ static int builtin_umask(char **argv) { - mode_t new_umask; - const char *arg = argv[1]; - if (arg) { -//TODO: umask may take chmod-like symbolic masks - new_umask = bb_strtou(arg, NULL, 8); - if (errno) { - //Message? bash examples: - //bash: umask: 'q': invalid symbolic mode operator - //bash: umask: 999: octal number out of range - return EXIT_FAILURE; + int rc; + mode_t mask; + + mask = umask(0); + if (argv[1]) { + mode_t old_mask = mask; + + mask ^= 0777; + rc = bb_parse_mode(argv[1], &mask); + mask ^= 0777; + if (rc == 0) { + mask = old_mask; + /* bash messages: + * bash: umask: 'q': invalid symbolic mode operator + * bash: umask: 999: octal number out of range + */ + bb_error_msg("%s: '%s' invalid mode", argv[0], argv[1]); } } else { - new_umask = umask(0); - printf("%.3o\n", (unsigned) new_umask); - /* fall through and restore new_umask which we set to 0 */ + rc = 1; + /* Mimic bash */ + printf("%04o\n", (unsigned) mask); + /* fall through and restore mask which we set to 0 */ } - umask(new_umask); - return EXIT_SUCCESS; + umask(mask); + + return !rc; /* rc != 0 - success */ } /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */ Index: shell/ash.c =================================================================== --- shell/ash.c (revision 26143) +++ shell/ash.c (revision 26144) @@ -12646,6 +12646,8 @@ S_IROTH, S_IWOTH, S_IXOTH }; + /* TODO: use bb_parse_mode() instead */ + char *ap; mode_t mask; int i; @@ -12712,7 +12714,6 @@ * * Public domain. */ - struct limits { uint8_t cmd; /* RLIMIT_xxx fit into it */ uint8_t factor_shift; /* shift by to get rlim_{cur,max} values */ ------------------------------------------------------------------------ r26143 | vda | 2009-04-17 20:23:21 -0500 (Fri, 17 Apr 2009) | 8 lines Changed paths: M /trunk/busybox/shell/hush.c hush: implement proper SIGHUP handling function old new delta check_and_run_traps 164 229 +65 insert_bg_job 376 366 -10 hush_main 937 927 -10 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26142) +++ shell/hush.c (revision 26143) @@ -52,11 +52,10 @@ * grep for "TODO" and fix (some of them are easy) * change { and } from special chars to reserved words * $var refs in function do not pick up values set by "var=val func" - * builtins: return, ulimit + * builtins: ulimit * follow IFS rules more precisely, including update semantics * figure out what to do with backslash-newline * continuation lines, both explicit and implicit - done? - * SIGHUP handling * separate job control from interactiveness * (testcase: booting with init=/bin/hush does not show prompt (2009-04)) * @@ -1070,8 +1069,9 @@ * "trap 'cmd' SIGxxx": * set bit in blocked_set (even if 'cmd' is '') * after [v]fork, if we plan to be a shell: - * nothing for {} child shell (say, "true | { true; true; } | true") - * unset all traps if () shell. + * unblock signals with special interactive handling + * (child shell is not interactive), + * unset all traps (note: regardless of child shell's type - {}, (), etc) * after [v]fork, if we plan to exec: * POSIX says pending signal mask is cleared in child - no need to clear it. * Restore blocked signal set to one inherited by shell just prior to exec. @@ -1084,9 +1084,9 @@ SPECIAL_INTERACTIVE_SIGS = 0 #if ENABLE_HUSH_JOB | (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP) + | (1 << SIGHUP) #endif | (1 << SIGTERM) -//TODO | (1 << SIGHUP) | (1 << SIGINT) }; @@ -1095,53 +1095,6 @@ // G.count_SIGCHLD++; //} -static int check_and_run_traps(int sig) -{ - static const struct timespec zero_timespec = { 0, 0 }; - smalluint save_rcode; - int last_sig = 0; - - if (sig) - goto jump_in; - while (1) { - sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec); - if (sig <= 0) - break; - jump_in: - last_sig = sig; - if (G.traps && G.traps[sig]) { - if (G.traps[sig][0]) { - /* We have user-defined handler */ - char *argv[] = { NULL, xstrdup(G.traps[sig]), NULL }; - save_rcode = G.last_exitcode; - builtin_eval(argv); - free(argv[1]); - G.last_exitcode = save_rcode; - } /* else: "" trap, ignoring signal */ - continue; - } - /* not a trap: special action */ - switch (sig) { -// case SIGCHLD: -// G.count_SIGCHLD++; -// break; - case SIGINT: -//TODO: add putchar('\n') also when we detect that child was killed (sleep 5 + ^C) - /* Builtin was ^C'ed, make it look prettier: */ - bb_putchar('\n'); - G.flag_SIGINT = 1; - break; -//TODO -// case SIGHUP: ... -// break; - default: /* ignored: */ - /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ - break; - } - } - return last_sig; -} - #if ENABLE_HUSH_JOB /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ @@ -1151,7 +1104,7 @@ /* Restores tty foreground process group, and exits. * May be called as signal handler for fatal signal - * (will faithfully resend signal to itself, producing correct exit state) + * (will resend signal to itself, producing correct exit state) * or called directly with -EXITCODE. * We also call it if xfunc is exiting. */ static void sigexit(int sig) NORETURN; @@ -1201,7 +1154,66 @@ #endif } +static int check_and_run_traps(int sig) +{ + static const struct timespec zero_timespec = { 0, 0 }; + smalluint save_rcode; + int last_sig = 0; + if (sig) + goto jump_in; + while (1) { + sig = sigtimedwait(&G.blocked_set, NULL, &zero_timespec); + if (sig <= 0) + break; + jump_in: + last_sig = sig; + if (G.traps && G.traps[sig]) { + if (G.traps[sig][0]) { + /* We have user-defined handler */ + char *argv[] = { NULL, xstrdup(G.traps[sig]), NULL }; + save_rcode = G.last_exitcode; + builtin_eval(argv); + free(argv[1]); + G.last_exitcode = save_rcode; + } /* else: "" trap, ignoring signal */ + continue; + } + /* not a trap: special action */ + switch (sig) { +// case SIGCHLD: +// G.count_SIGCHLD++; +// break; + case SIGINT: +//TODO: add putchar('\n') also when we detect that child was killed (sleep 5 + ^C) + /* Builtin was ^C'ed, make it look prettier: */ + bb_putchar('\n'); + G.flag_SIGINT = 1; + break; +#if ENABLE_HUSH_JOB + case SIGHUP: { + struct pipe *job; + /* bash is observed to signal whole process groups, + * not individual processes */ + for (job = G.job_list; job; job = job->next) { + if (job->pgrp <= 0) + continue; + debug_printf_exec("HUPing pgrp %d\n", job->pgrp); + if (kill(- job->pgrp, SIGHUP) == 0) + kill(- job->pgrp, SIGCONT); + } + sigexit(SIGHUP); + } +#endif + default: /* ignored: */ + /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ + break; + } + } + return last_sig; +} + + static const char *set_cwd(void) { /* xrealloc_getcwd_or_warn(arg) calls free(arg), @@ -2061,7 +2073,9 @@ case '`': /* `cmd */ *p = '\0'; arg++; -//TODO: can we just stuff it into "output" directly? + /* Can't just stuff it into output o_string, + * expanded result may need to be globbed + * and $IFS-splitted */ debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); process_command_subs(&subst_result, arg); debug_printf_subst("SUBST RES '%s'\n", subst_result.data); @@ -2777,7 +2791,8 @@ } funcp = funcp->next; } - debug_printf_exec("found function '%s'\n", name); + if (funcp) + debug_printf_exec("found function '%s'\n", name); return funcp; } @@ -2819,7 +2834,7 @@ } goto skip; } - debug_printf_exec("remembering new function '%s'\n", command->argv[0]); + debug_printf_exec("remembering new function '%s'\n", name); funcp = *funcpp = xzalloc(sizeof(*funcp)); /*funcp->next = NULL;*/ skip: @@ -3059,8 +3074,11 @@ } len = 0; - do len += strlen(*argv) + 1; while (*++argv); - pi->cmdtext = p = xmalloc(len); + do { + len += strlen(*argv) + 1; + } while (*++argv); + p = xmalloc(len); + pi->cmdtext = p;// = xmalloc(len); argv = pi->cmds[0].argv; do { len = strlen(*argv); @@ -3074,44 +3092,36 @@ static void insert_bg_job(struct pipe *pi) { - struct pipe *thejob; + struct pipe *job, **jobp; int i; /* Linear search for the ID of the job to use */ pi->jobid = 1; - for (thejob = G.job_list; thejob; thejob = thejob->next) - if (thejob->jobid >= pi->jobid) - pi->jobid = thejob->jobid + 1; + for (job = G.job_list; job; job = job->next) + if (job->jobid >= pi->jobid) + pi->jobid = job->jobid + 1; - /* Add thejob to the list of running jobs */ - if (!G.job_list) { - thejob = G.job_list = xmalloc(sizeof(*thejob)); - } else { - for (thejob = G.job_list; thejob->next; thejob = thejob->next) - continue; - thejob->next = xmalloc(sizeof(*thejob)); - thejob = thejob->next; - } + /* Add job to the list of running jobs */ + jobp = &G.job_list; + while ((job = *jobp) != NULL) + jobp = &job->next; + job = *jobp = xmalloc(sizeof(*job)); - /* Physically copy the struct job */ - memcpy(thejob, pi, sizeof(struct pipe)); - thejob->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds); - /* We cannot copy entire pi->cmds[] vector! Double free()s will happen */ + *job = *pi; /* physical copy */ + job->next = NULL; + job->cmds = xzalloc(sizeof(pi->cmds[0]) * pi->num_cmds); + /* Cannot copy entire pi->cmds[] vector! This causes double frees */ for (i = 0; i < pi->num_cmds; i++) { -// TODO: do we really need to have so many fields which are just dead weight -// at execution stage? - thejob->cmds[i].pid = pi->cmds[i].pid; + job->cmds[i].pid = pi->cmds[i].pid; /* all other fields are not used and stay zero */ } - thejob->next = NULL; - thejob->cmdtext = xstrdup(get_cmdtext(pi)); + job->cmdtext = xstrdup(get_cmdtext(pi)); - /* We don't wait for background thejobs to return -- append it - to the list of backgrounded thejobs and leave it alone */ if (G_interactive_fd) - printf("[%d] %d %s\n", thejob->jobid, thejob->cmds[0].pid, thejob->cmdtext); - G.last_bg_pid = thejob->cmds[0].pid; - G.last_jobid = thejob->jobid; + printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext); + /* Last command's pid goes to $! */ + G.last_bg_pid = job->cmds[job->num_cmds - 1].pid; + G.last_jobid = job->jobid; } static void remove_bg_job(struct pipe *pi) @@ -3306,7 +3316,7 @@ * cmd || ... { list } || ... * If it is, then we can run cmd as a builtin, NOFORK [do we do this?], * or (if SH_STANDALONE) an applet, and we can run the { list } - * with run_list(). If it isn't one of these, we fork and exec cmd. + * with run_list. If it isn't one of these, we fork and exec cmd. * * Cases when we must fork: * non-single: cmd | cmd @@ -3942,7 +3952,11 @@ check_and_run_traps(0); #if ENABLE_HUSH_JOB if (G.run_list_level == 1) +{ +debug_printf_exec("insert_bg_job1\n"); insert_bg_job(pi); +debug_printf_exec("insert_bg_job2\n"); +} #endif G.last_exitcode = rcode = EXIT_SUCCESS; debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); @@ -5853,11 +5867,10 @@ /* bash 3.2 seems to handle these just like 'fatal' ones */ maybe_set_to_sigexit(SIGPIPE); maybe_set_to_sigexit(SIGALRM); -//TODO: disable and move down when proper SIGHUP handling is added - maybe_set_to_sigexit(SIGHUP ); - /* if we are interactive, [SIGHUP,] SIGTERM and SIGINT are masked. + /* if we are interactive, SIGHUP, SIGTERM and SIGINT are masked. * if we aren't interactive... but in this case * we never want to restore pgrp on exit, and this fn is not called */ + /*maybe_set_to_sigexit(SIGHUP );*/ /*maybe_set_to_sigexit(SIGTERM);*/ /*maybe_set_to_sigexit(SIGINT );*/ } @@ -6350,7 +6363,7 @@ #if !BB_MMU nommu_save_t dummy; #endif -// TODO: if exec fails, bash does NOT exit! We do... + /* TODO: if exec fails, bash does NOT exit! We do... */ pseudo_exec_argv(&dummy, argv, 0, NULL); /* never returns */ } @@ -6472,8 +6485,8 @@ bb_error_msg("%s: %d: no such job", argv[0], jobnum); return EXIT_FAILURE; found: - // TODO: bash prints a string representation - // of job being foregrounded (like "sleep 1 | cat") + /* TODO: bash prints a string representation + * of job being foregrounded (like "sleep 1 | cat") */ if (argv[0][0] == 'f') { /* Put the job into the foreground. */ tcsetpgrp(G_interactive_fd, pi->pgrp); @@ -6705,7 +6718,7 @@ if (*++argv == NULL) return EXIT_FAILURE; - /* TODO: search through $PATH is missing */ +// TODO: search through $PATH is missing input = fopen_or_warn(*argv, "r"); if (!input) { /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ ------------------------------------------------------------------------ r26142 | vda | 2009-04-17 18:53:15 -0500 (Fri, 17 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c builtin_return's parameter is not unused ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26141) +++ shell/hush.c (revision 26142) @@ -6904,7 +6904,7 @@ #endif #if ENABLE_HUSH_FUNCTIONS -static int builtin_return(char **argv UNUSED_PARAM) +static int builtin_return(char **argv) { int rc; ------------------------------------------------------------------------ r26141 | vda | 2009-04-17 18:44:18 -0500 (Fri, 17 Apr 2009) | 4 lines Changed paths: M /trunk/busybox/shell/hush.c A /trunk/busybox/shell/hush_test/hush-misc/func3.right A /trunk/busybox/shell/hush_test/hush-misc/func3.tests hush: return builtin by Bayram Kurumahmut (kbayram AT ubicom.com) ~+200 bytes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26140) +++ shell/hush.c (revision 26141) @@ -444,6 +444,13 @@ #if ENABLE_HUSH_LOOPS smallint flag_break_continue; #endif +#if ENABLE_HUSH_FUNCTIONS + /* 0: outside of a function (or sourced file) + * -1: inside of a function, ok to use return builtin + * 1: return is invoked, skip all till end of func. + */ + smallint flag_return_in_progress; +#endif smallint fake_mode; smallint exiting; /* used to prevent EXIT trap recursion */ /* These four support $?, $#, and $1 */ @@ -522,6 +529,9 @@ static int builtin_break(char **argv); static int builtin_continue(char **argv); #endif +#if ENABLE_HUSH_FUNCTIONS +static int builtin_return(char **argv); +#endif /* Table of built-in functions. They can be forked or not, depending on * context: within pipes, they fork. As simple commands, they do not. @@ -575,7 +585,9 @@ #endif BLTIN("pwd" , builtin_pwd , "Print current directory"), BLTIN("read" , builtin_read , "Input environment variable"), -// BLTIN("return" , builtin_return , "Return from a function"), +#if ENABLE_HUSH_FUNCTIONS + BLTIN("return" , builtin_return , "Return from a function"), +#endif BLTIN("set" , builtin_set , "Set/unset shell local variables"), BLTIN("shift" , builtin_shift , "Shift positional parameters"), BLTIN("test" , builtin_test , "Test condition"), @@ -2849,9 +2861,14 @@ static int run_function(const struct function *funcp, char **argv) { int rc; + smallint sv_flg; save_arg_t sv; save_and_replace_G_args(&sv, argv); + /* "we are in function, ok to use return" */ + sv_flg = G.flag_return_in_progress; + G.flag_return_in_progress = -1; + /* On MMU, funcp->body is always non-NULL */ #if !BB_MMU if (!funcp->body) { @@ -2863,6 +2880,8 @@ { rc = run_list(funcp->body); } + + G.flag_return_in_progress = sv_flg; restore_G_args(&sv, argv); return rc; @@ -3886,7 +3905,8 @@ #endif rcode = r = run_pipe(pi); /* NB: rcode is a smallint */ if (r != -1) { - /* We only ran a builtin: rcode is already known + /* We ran a builtin, function, or group. + * rcode is already known * and we don't need to wait for anything. */ G.last_exitcode = rcode; debug_printf_exec(": builtin/func exitcode %d\n", rcode); @@ -3910,6 +3930,10 @@ continue; } #endif +#if ENABLE_HUSH_FUNCTIONS + if (G.flag_return_in_progress == 1) + goto check_jobs_and_break; +#endif } else if (pi->followup == PIPE_BG) { /* What does bash do with attempts to background builtins? */ /* even bash 3.2 doesn't do that well with nested bg: @@ -6675,6 +6699,7 @@ static int builtin_source(char **argv) { FILE *input; + smallint sv_flg; save_arg_t sv; if (*++argv == NULL) @@ -6688,12 +6713,17 @@ } close_on_exec_on(fileno(input)); - /* Now run the file */ + sv_flg = G.flag_return_in_progress; + /* "we are inside sourced file, ok to use return" */ + G.flag_return_in_progress = -1; save_and_replace_G_args(&sv, argv); + parse_and_run_file(input); - restore_G_args(&sv, argv); fclose(input); + restore_G_args(&sv, argv); + G.flag_return_in_progress = sv_flg; + return G.last_exitcode; } @@ -6833,25 +6863,36 @@ return ret; } +#if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS +static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min) +{ + if (argv[1]) { + def = bb_strtou(argv[1], NULL, 10); + if (errno || def < def_min || argv[2]) { + bb_error_msg("%s: bad arguments", argv[0]); + def = UINT_MAX; + } + } + return def; +} +#endif + #if ENABLE_HUSH_LOOPS static int builtin_break(char **argv) { + unsigned depth; if (G.depth_of_loop == 0) { bb_error_msg("%s: only meaningful in a loop", argv[0]); return EXIT_SUCCESS; /* bash compat */ } G.flag_break_continue++; /* BC_BREAK = 1 */ - G.depth_break_continue = 1; - if (argv[1]) { - G.depth_break_continue = bb_strtou(argv[1], NULL, 10); - if (errno || !G.depth_break_continue || argv[2]) { - bb_error_msg("%s: bad arguments", argv[0]); - G.flag_break_continue = BC_BREAK; - G.depth_break_continue = UINT_MAX; - } - } - if (G.depth_of_loop < G.depth_break_continue) + + G.depth_break_continue = depth = parse_numeric_argv1(argv, 1, 1); + if (depth == UINT_MAX) + G.flag_break_continue = BC_BREAK; + if (G.depth_of_loop < depth) G.depth_break_continue = G.depth_of_loop; + return EXIT_SUCCESS; } @@ -6861,3 +6902,27 @@ return builtin_break(argv); } #endif + +#if ENABLE_HUSH_FUNCTIONS +static int builtin_return(char **argv UNUSED_PARAM) +{ + int rc; + + if (G.flag_return_in_progress != -1) { + bb_error_msg("%s: not in a function or sourced script", argv[0]); + return EXIT_FAILURE; /* bash compat */ + } + + G.flag_return_in_progress = 1; + + /* bash: + * out of range: wraps around at 256, does not error out + * non-numeric param: + * f() { false; return qwe; }; f; echo $? + * bash: return: qwe: numeric argument required <== we do this + * 255 <== we also do this + */ + rc = parse_numeric_argv1(argv, G.last_exitcode, 0); + return rc; +} +#endif Index: shell/hush_test/hush-misc/func3.right =================================================================== --- shell/hush_test/hush-misc/func3.right (revision 0) +++ shell/hush_test/hush-misc/func3.right (revision 26141) @@ -0,0 +1,4 @@ +One:1 +Zero:0 +One:1 +Five:5 Index: shell/hush_test/hush-misc/func3.tests =================================================================== --- shell/hush_test/hush-misc/func3.tests (revision 0) +++ shell/hush_test/hush-misc/func3.tests (revision 26141) @@ -0,0 +1,8 @@ +f() { false; return; echo BAD; }; +{ f; echo One:$?; }; echo Zero:$? + +f() { false; return; }; +f; echo One:$? + +f() { return 5; }; +f; echo Five:$? Property changes on: shell/hush_test/hush-misc/func3.tests ___________________________________________________________________ Name: svn:executable + * ------------------------------------------------------------------------ r26140 | vda | 2009-04-17 17:20:44 -0500 (Fri, 17 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/include/platform.h fix move_to_unaligned32 ------------------------------------------------------------------------ Index: include/platform.h =================================================================== --- include/platform.h (revision 26139) +++ include/platform.h (revision 26140) @@ -173,7 +173,10 @@ /* performs reasonably well (gcc usually inlines memcpy here) */ #define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) #define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) -#define move_to_unaligned32(u32p, v) (memcpy((u32p), &(v), 4)) +#define move_to_unaligned32(u32p, v) do { \ + uint32_t __t = (v); \ + memcpy((u32p), &__t, 4); \ +} while (0) #endif /* ---- Networking ------------------------------------------ */ ------------------------------------------------------------------------ r26139 | vda | 2009-04-17 16:56:02 -0500 (Fri, 17 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/applets/Kbuild build system: remove some unnecessary rebuilds ------------------------------------------------------------------------ Index: applets/Kbuild =================================================================== --- applets/Kbuild (revision 26138) +++ applets/Kbuild (revision 26139) @@ -13,18 +13,21 @@ always:= $(hostprogs-y) # Generated files need additional love +# NB: __srctree is either empty or "srctree/" +# using it instead of srctree decreases amount of rebuilds +# if tree is merely renamed/copied -HOSTCFLAGS_usage.o = -I$(srctree)/include +HOSTCFLAGS_usage.o = -I$(__srctree)include applets/applets.o: include/usage_compressed.h include/applet_tables.h -applets/usage: .config $(srctree)/applets/usage_compressed +applets/usage: .config $(__srctree)applets/usage_compressed applets/applet_tables: .config quiet_cmd_gen_usage_compressed = GEN include/usage_compressed.h - cmd_gen_usage_compressed = $(srctree)/applets/usage_compressed include/usage_compressed.h applets + cmd_gen_usage_compressed = $(__srctree)applets/usage_compressed include/usage_compressed.h applets -include/usage_compressed.h: applets/usage $(srctree)/applets/usage_compressed +include/usage_compressed.h: applets/usage $(__srctree)applets/usage_compressed $(call cmd,gen_usage_compressed) quiet_cmd_gen_applet_tables = GEN include/applet_tables.h ------------------------------------------------------------------------ r26138 | vda | 2009-04-17 13:54:50 -0500 (Fri, 17 Apr 2009) | 11 lines Changed paths: M /trunk/busybox/shell/hush.c hush: set $n properly for "source" builtin function old new delta restore_G_args - 78 +78 save_and_replace_G_args - 64 +64 builtin_source 72 107 +35 run_list 2549 2367 -182 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 1/1 up/down: 177/-182) Total: -5 bytes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26137) +++ shell/hush.c (revision 26138) @@ -939,6 +939,52 @@ } +/* Helpers for setting new $n and restoring them back + */ +typedef struct save_arg_t { + char *sv_argv0; + char **sv_g_argv; + int sv_g_argc; + smallint sv_g_malloced; +} save_arg_t; + +static void save_and_replace_G_args(save_arg_t *sv, char **argv) +{ + int n; + + sv->sv_argv0 = argv[0]; + sv->sv_g_argv = G.global_argv; + sv->sv_g_argc = G.global_argc; + sv->sv_g_malloced = G.global_args_malloced; + + argv[0] = G.global_argv[0]; /* retain $0 */ + G.global_argv = argv; + G.global_args_malloced = 0; + + n = 1; + while (*++argv) + n++; + G.global_argc = n; +} + +static void restore_G_args(save_arg_t *sv, char **argv) +{ + char **pp; + + if (G.global_args_malloced) { + /* someone ran "set -- arg1 arg2 ...", undo */ + pp = G.global_argv; + while (*++pp) /* note: does not free $0 */ + free(*pp); + free(G.global_argv); + } + argv[0] = sv->sv_argv0; + G.global_argv = sv->sv_g_argv; + G.global_argc = sv->sv_g_argc; + G.global_args_malloced = sv->sv_g_malloced; +} + + /* Basic theory of signal handling in shell * ======================================== * This does not describe what hush does, rather, it is current understanding @@ -2802,54 +2848,24 @@ static int run_function(const struct function *funcp, char **argv) { - int n; - char **pp; - char *sv_argv0; - smallint sv_g_malloced; - int sv_g_argc; - char **sv_g_argv; + int rc; + save_arg_t sv; - sv_argv0 = argv[0]; - sv_g_malloced = G.global_args_malloced; - sv_g_argc = G.global_argc; - sv_g_argv = G.global_argv; - - pp = argv; - n = 1; - while (*++pp) - n++; - - argv[0] = G.global_argv[0]; /* retain $0 */ - G.global_args_malloced = 0; - G.global_argc = n; - G.global_argv = argv; - + save_and_replace_G_args(&sv, argv); /* On MMU, funcp->body is always non-NULL */ #if !BB_MMU if (!funcp->body) { /* Function defined by -F */ parse_and_run_string(funcp->body_as_string); - n = G.last_exitcode; + rc = G.last_exitcode; } else #endif { - n = run_list(funcp->body); + rc = run_list(funcp->body); } + restore_G_args(&sv, argv); - if (G.global_args_malloced) { - /* function ran "set -- arg1 arg2 ..." */ - pp = G.global_argv; - while (*++pp) - free(*pp); - free(G.global_argv); - } - - argv[0] = sv_argv0; - G.global_args_malloced = sv_g_malloced; - G.global_argc = sv_g_argc; - G.global_argv = sv_g_argv; - - return n; + return rc; } #endif @@ -6659,6 +6675,7 @@ static int builtin_source(char **argv) { FILE *input; + save_arg_t sv; if (*++argv == NULL) return EXIT_FAILURE; @@ -6672,11 +6689,11 @@ close_on_exec_on(fileno(input)); /* Now run the file */ - /* TODO: argv and argc are broken; need to save old G.global_argv - * (pointer only is OK!) on this stack frame, - * set G.global_argv=argv+1, recurse, and restore. */ + save_and_replace_G_args(&sv, argv); parse_and_run_file(input); + restore_G_args(&sv, argv); fclose(input); + return G.last_exitcode; } ------------------------------------------------------------------------ r26135 | vda | 2009-04-17 09:35:43 -0500 (Fri, 17 Apr 2009) | 6 lines Changed paths: M /trunk/busybox/shell/hush.c hush: fix non-interactive response to pipe being stopped. function old new delta checkjobs 380 394 +14 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26134) +++ shell/hush.c (revision 26135) @@ -2863,7 +2863,7 @@ /* Called after [v]fork() in run_pipe, or from builtin_exec. * Never returns. - * XXX no exit() here. If you don't exec, use _exit instead. + * Don't exit() here. If you don't exec, use _exit instead. * The at_exit handlers apparently confuse the calling process, * in particular stdin handling. Not sure why? -- because of vfork! (vda) */ static void pseudo_exec_argv(nommu_save_t *nommu_save, @@ -3136,12 +3136,8 @@ * [3]+ Stopped sleep 20 | false * bash-3.00# echo $? * 1 <========== bg pipe is not fully done, but exitcode is already known! + * [hush 1.14.0: yes we do it right] */ - -//FIXME: non-interactive bash does not continue even if all processes in fg pipe -//are stopped. Testcase: "cat | cat" in a script (not on command line) -// + killall -STOP cat - wait_more: while (1) { int i; @@ -3175,7 +3171,6 @@ debug_printf_jobs("check pid %d\n", fg_pipe->cmds[i].pid); if (fg_pipe->cmds[i].pid != childpid) continue; - /* printf("process %d exit %d\n", i, WEXITSTATUS(status)); */ if (dead) { fg_pipe->cmds[i].pid = 0; fg_pipe->alive_cmds--; @@ -3191,12 +3186,17 @@ debug_printf_jobs("fg_pipe: alive_cmds %d stopped_cmds %d\n", fg_pipe->alive_cmds, fg_pipe->stopped_cmds); if (fg_pipe->alive_cmds - fg_pipe->stopped_cmds <= 0) { - /* All processes in fg pipe have exited/stopped */ + /* All processes in fg pipe have exited or stopped */ +/* Note: *non-interactive* bash does not continue if all processes in fg pipe + * are stopped. Testcase: "cat | cat" in a script (not on command line!) + * and "killall -STOP cat" */ + if (G_interactive_fd) { #if ENABLE_HUSH_JOB - if (fg_pipe->alive_cmds) - insert_bg_job(fg_pipe); + if (fg_pipe->alive_cmds) + insert_bg_job(fg_pipe); #endif - return rcode; + return rcode; + } } /* There are still running processes in the fg pipe */ goto wait_more; /* do waitpid again */ @@ -3400,10 +3400,10 @@ goto clean_up_and_ret1; } } - /* XXX setup_redirects acts on file descriptors, not FILEs. + /* setup_redirects acts on file descriptors, not FILEs. * This is perfect for work that comes after exec(). * Is it really safe for inline use? Experimentally, - * things seem to work with glibc. */ + * things seem to work. */ rcode = setup_redirects(command, squirrel); if (rcode == 0) { new_env = expand_assignments(argv, command->assignment_cnt); @@ -5026,7 +5026,7 @@ o_addchr(dest, SPECIAL_VAR_SYMBOL); ch = i_getch(input); nommu_addchr(as_string, ch); - /* XXX maybe someone will try to escape the '}' */ + /* TODO: maybe someone will try to escape the '}' */ expansion = 0; first_char = true; all_digits = false; @@ -5992,7 +5992,7 @@ /* If we are login shell... */ if (argv[0] && argv[0][0] == '-') { FILE *input; - /* XXX what should argv be while sourcing /etc/profile? */ + /* TODO: what should argv be while sourcing /etc/profile? */ debug_printf("sourcing /etc/profile\n"); input = fopen_for_read("/etc/profile"); if (input != NULL) { @@ -6310,7 +6310,7 @@ #if !BB_MMU nommu_save_t dummy; #endif -// FIXME: if exec fails, bash does NOT exit! We do... +// TODO: if exec fails, bash does NOT exit! We do... pseudo_exec_argv(&dummy, argv, 0, NULL); /* never returns */ } @@ -6663,7 +6663,7 @@ if (*++argv == NULL) return EXIT_FAILURE; - /* XXX search through $PATH is missing */ + /* TODO: search through $PATH is missing */ input = fopen_or_warn(*argv, "r"); if (!input) { /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ @@ -6672,8 +6672,7 @@ close_on_exec_on(fileno(input)); /* Now run the file */ -//TODO: - /* XXX argv and argc are broken; need to save old G.global_argv + /* TODO: argv and argc are broken; need to save old G.global_argv * (pointer only is OK!) on this stack frame, * set G.global_argv=argv+1, recurse, and restore. */ parse_and_run_file(input); ------------------------------------------------------------------------ r26132 | vda | 2009-04-17 08:52:51 -0500 (Fri, 17 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: unblock TERM, INT, HUP in child shells too. ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26131) +++ shell/hush.c (revision 26132) @@ -1022,6 +1022,15 @@ * are to count SIGCHLDs [disabled - bug somewhere, + bloat] * and to restore tty pgrp on signal-induced exit. */ +enum { + SPECIAL_INTERACTIVE_SIGS = 0 +#if ENABLE_HUSH_JOB + | (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP) +#endif + | (1 << SIGTERM) +//TODO | (1 << SIGHUP) + | (1 << SIGINT) +}; //static void SIGCHLD_handler(int sig UNUSED_PARAM) //{ @@ -1059,6 +1068,8 @@ // G.count_SIGCHLD++; // break; case SIGINT: +//TODO: add putchar('\n') also when we detect that child was killed (sleep 5 + ^C) + /* Builtin was ^C'ed, make it look prettier: */ bb_putchar('\n'); G.flag_SIGINT = 1; break; @@ -2284,37 +2295,46 @@ static void reset_traps_to_defaults(void) { - enum { - JOBSIGS = (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP) - }; - unsigned sig; - - if (!G.traps && !(G.non_DFL_mask & JOBSIGS)) - return; - - /* This function is always called in a child shell. + /* This function is always called in a child shell + * after fork (not vfork, NOMMU doesn't use this function). * Child shells are not interactive. * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling. * Testcase: (while :; do :; done) + ^Z should background. + * Same goes for SIGTERM, SIGHUP, SIGINT. */ - G.non_DFL_mask &= ~JOBSIGS; - sigdelset(&G.blocked_set, SIGTTIN); - sigdelset(&G.blocked_set, SIGTTOU); - sigdelset(&G.blocked_set, SIGTSTP); + unsigned sig; + unsigned mask; - if (G.traps) for (sig = 0; sig < NSIG; sig++) { - if (!G.traps[sig]) { + if (!G.traps && !(G.non_DFL_mask & SPECIAL_INTERACTIVE_SIGS)) + return; + + /* Stupid. It can be done with *single* &= op, but we can't use + * the fact that G.blocked_set is implemented as a bitmask... */ + mask = (SPECIAL_INTERACTIVE_SIGS >> 1); + sig = 1; + while (1) { + if (mask & 1) + sigdelset(&G.blocked_set, sig); + mask >>= 1; + if (!mask) + break; + sig++; + } + + G.non_DFL_mask &= ~SPECIAL_INTERACTIVE_SIGS; + mask = G.non_DFL_mask; + if (G.traps) for (sig = 0; sig < NSIG; sig++, mask >>= 1) { + if (!G.traps[sig]) continue; - } free(G.traps[sig]); G.traps[sig] = NULL; /* There is no signal for 0 (EXIT) */ if (sig == 0) continue; - /* there was a trap handler, we are removing it - * (if sig has non-DFL handling, - * we don't need to do anything) */ - if (sig < 32 && (G.non_DFL_mask & (1 << sig))) + /* There was a trap handler, we are removing it. + * But if sig still has non-DFL handling, + * we should not unblock it. */ + if (mask & 1) continue; sigdelset(&G.blocked_set, sig); } @@ -5740,17 +5760,8 @@ unsigned mask; mask = (1 << SIGQUIT); - if (G_interactive_fd) { - mask = 0 - | (1 << SIGQUIT) - | (1 << SIGTERM) -//TODO | (1 << SIGHUP) -#if ENABLE_HUSH_JOB - | (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP) -#endif - | (1 << SIGINT) - ; - } + if (G_interactive_fd) + mask = (1 << SIGQUIT) | SPECIAL_INTERACTIVE_SIGS; G.non_DFL_mask = mask; if (!second_time) ------------------------------------------------------------------------ r26131 | vda | 2009-04-17 06:55:42 -0500 (Fri, 17 Apr 2009) | 10 lines Changed paths: M /trunk/busybox/shell/hush.c hush: disallow "{echo hi; }" (require whitespace) and "{ echo hi }" (require semicolon or &) function old new delta parse_stream 2098 2176 +78 done_command 98 84 -14 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 78/-14) Total: 64 bytes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26130) +++ shell/hush.c (revision 26131) @@ -319,7 +319,11 @@ */ struct redir_struct *redirects; /* I/O redirections */ }; +/* Is there anything in this command at all? */ +#define IS_NULL_CMD(cmd) \ + (!(cmd)->group && !(cmd)->argv && !(cmd)->redirects) + struct pipe { struct pipe *next; int num_cmds; /* total number of commands in pipe */ @@ -341,6 +345,9 @@ PIPE_OR = 3, PIPE_BG = 4, } pipe_style; +/* Is there anything in this pipe at all? */ +#define IS_NULL_PIPE(pi) \ + ((pi)->num_cmds == 0 IF_HAS_KEYWORDS( && (pi)->res_word == RES_NONE)) /* This holds pointers to the various results of parsing */ struct parse_context { @@ -3971,8 +3978,10 @@ return pi; } -/* Command (member of a pipe) is complete. The only possible error here - * is out of memory, in which case xmalloc exits. */ +/* Command (member of a pipe) is complete, or we start a new pipe + * if ctx->command is NULL. + * No errors possible here. + */ static int done_command(struct parse_context *ctx) { /* The command is really already in the pipe structure, so @@ -3981,13 +3990,9 @@ struct command *command = ctx->command; if (command) { - if (command->group == NULL - && command->argv == NULL - && command->redirects == NULL - ) { + if (IS_NULL_CMD(command)) { debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds); - memset(command, 0, sizeof(*command)); /* paranoia */ - return pi->num_cmds; + goto clear_and_ret; } pi->num_cmds++; debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds); @@ -3999,12 +4004,9 @@ /* Only real trickiness here is that the uncommitted * command structure is not counted in pi->num_cmds. */ pi->cmds = xrealloc(pi->cmds, sizeof(*pi->cmds) * (pi->num_cmds+1)); - command = &pi->cmds[pi->num_cmds]; + ctx->command = command = &pi->cmds[pi->num_cmds]; + clear_and_ret: memset(command, 0, sizeof(*command)); - - ctx->command = command; - /* but ctx->pipe and ctx->list_head remain unchanged */ - return pi->num_cmds; /* used only for 0/nonzero check */ } @@ -4024,9 +4026,7 @@ /* Without this check, even just on command line generates * tree of three NOPs (!). Which is harmless but annoying. - * IOW: it is safe to do it unconditionally. - * RES_NONE case is for "for a in; do ..." (empty IN set) - * and other cases to work. */ + * IOW: it is safe to do it unconditionally. */ if (not_null #if ENABLE_HUSH_IF || ctx->ctx_res_w == RES_FI @@ -4048,7 +4048,7 @@ ctx->pipe->next = new_p; ctx->pipe = new_p; /* RES_THEN, RES_DO etc are "sticky" - - * they remain set for commands inside if/while. + * they remain set for pipes inside if/while. * This is used to control execution. * RES_FOR and RES_IN are NOT sticky (needed to support * cases where variable or value happens to match a keyword): @@ -4304,7 +4304,7 @@ && ctx->ctx_res_w != RES_IN # endif ) { - debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); + debug_printf_parse("checking '%s' for reserved-ness\n", word->data); if (reserved_word(word, ctx)) { o_reset_to_empty_unquoted(word); debug_printf_parse("done_word return %d\n", @@ -4775,6 +4775,14 @@ if (ch == '(') { endch = ')'; command->grp_type = GRP_SUBSHELL; + } else { + /* bash does not allow "{echo...", requires whitespace */ + ch = i_getch(input); + if (ch != ' ' && ch != '\t' && ch != '\n') { + syntax_error_unexpected_ch(ch); + return 1; + } + nommu_addchr(&ctx->as_string, ch); } { @@ -5352,13 +5360,11 @@ if (end_trigger && end_trigger == ch && (heredoc_cnt == 0 || end_trigger != ';') ) { -//TODO: disallow "{ cmd }" without semicolon if (heredoc_cnt) { /* This is technically valid: * { cat < ------------------------------------------------------------------------ r26127 | vda | 2009-04-16 19:01:04 -0500 (Thu, 16 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/mdev.c mdev: add large comment, fix a buglet with subsystem and /sys/block ------------------------------------------------------------------------ Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26126) +++ util-linux/mdev.c (revision 26127) @@ -10,6 +10,41 @@ #include "libbb.h" #include "xregex.h" +/* "mdev -s" scans /sys/class/xxx, looking for directories which have dev + * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev + * contains "4:0\n". Directory name is taken as device name, path component + * directly after /sys/class/ as subsystem. In this example, "tty0" and "tty". + * Then mdev creates the /dev/device_name node. + * + * mdev w/o parameters is called as hotplug helper. It takes device + * and subsystem names from $DEVPATH and $SUBSYSTEM, extracts + * maj,min from "/sys/$DEVPATH/dev" and also examines + * $ACTION ("add"/"delete") and $FIRMWARE. + * + * If action is "add", mdev creates /dev/device_name similarly to mdev -s. + * (todo: explain "delete" and $FIRMWARE) + * + * If /etc/mdev.conf exists, it may modify /dev/device_name's properties. + * /etc/mdev.conf file format: + * + * [-][subsystem/]device user:grp mode [>|=path] [@|$|*command args...] + * [-]@maj,min[-min2] user:grp mode [>|=path] [@|$|*command args...] + * + * The device name or "subsystem/device" combo is matched against 1st field + * (which is a regex), or maj,min is matched against 1st field. + * + * Leading minus in 1st field means "don't stop on this line", otherwise + * search is stopped after the matching line is encountered. + * + * When line matches, the device node is created, chmod'ed and chown'ed. + * Then it moved to path, and if >path, a symlink to moved node is created + * Examples: + * =loop/ - moves to /dev/loop + * >disk/sda%1 - moves to /dev/disk/sdaN, makes /dev/sdaN a symlink + * Then "command args" is executed (via sh -c 'command args'). + * @:execute on creation, $:on deletion, *:on both. + */ + struct globals { int root_major, root_minor; char *subsystem; @@ -96,8 +131,11 @@ if (strstr(path, "/block/")) type = S_IFBLK; - /* Make path point to subsystem/device_name */ - path += sizeof("/sys/class/") - 1; + /* Make path point to "subsystem/device_name" */ + if (path[5] == 'b') /* legacy /sys/block? */ + path += sizeof("/sys/") - 1; + else + path += sizeof("/sys/class/") - 1; #if !ENABLE_FEATURE_MDEV_CONF mode = 0660; @@ -131,8 +169,8 @@ keep_matching = ('-' == val[0]); val += keep_matching; /* swallow leading dash */ - /* Match against either subsystem/device_name - * or device_name alone */ + /* Match against either "subsystem/device_name" + * or "device_name" alone */ name = strchr(val, '/') ? path : (char *) device_name; /* Fields: regex uid:gid mode [alias] [cmd] */ ------------------------------------------------------------------------ r26126 | vda | 2009-04-16 18:05:59 -0500 (Thu, 16 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/scripts/defconfig disable FLASH_ERASEALL in defconfig ------------------------------------------------------------------------ Index: scripts/defconfig =================================================================== --- scripts/defconfig (revision 26125) +++ scripts/defconfig (revision 26126) @@ -579,7 +579,7 @@ CONFIG_EJECT=y CONFIG_FEATURE_EJECT_SCSI=y CONFIG_FBSPLASH=y -CONFIG_FLASH_ERASEALL=y +# CONFIG_FLASH_ERASEALL is not set CONFIG_IONICE=y # CONFIG_INOTIFYD is not set CONFIG_LAST=y ------------------------------------------------------------------------ r26125 | vda | 2009-04-16 17:42:01 -0500 (Thu, 16 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/testsuite/mdev.tests M /trunk/busybox/util-linux/mdev.c mdev: set mode, needed when device node already exists. ------------------------------------------------------------------------ Index: testsuite/mdev.tests =================================================================== --- testsuite/mdev.tests (revision 26124) +++ testsuite/mdev.tests (revision 26125) @@ -49,6 +49,18 @@ # continuing to use directory structure from prev test rm -rf mdev.testdir/dev/* +echo "-.* 1:1 666" >mdev.testdir/etc/mdev.conf +echo "sda 2:2 444" >>mdev.testdir/etc/mdev.conf +testing "mdev does not stop on dash-rule" \ + "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; + ls -ln mdev.testdir/dev | $FILTER_LS" \ +"\ +br--r--r-- 1 2 2 8,0 sda +" \ + "" "" + +# continuing to use directory structure from prev test +rm -rf mdev.testdir/dev/* echo "sda 0:0 444 >disk/scsiA" >mdev.testdir/etc/mdev.conf testing "mdev move/symlink rule '>bar/baz'" \ "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26124) +++ util-linux/mdev.c (revision 26125) @@ -274,6 +274,7 @@ if (major == root_major && minor == root_minor) symlink(device_name, "root"); #if ENABLE_FEATURE_MDEV_CONF + chmod(device_name, mode); chown(device_name, ugid.uid, ugid.gid); # if ENABLE_FEATURE_MDEV_RENAME if (alias) { ------------------------------------------------------------------------ r26124 | vda | 2009-04-16 16:42:12 -0500 (Thu, 16 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/mdev.c mdev: change subsystem syntax from /subsystem to subsystem/devname ------------------------------------------------------------------------ Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26123) +++ util-linux/mdev.c (revision 26124) @@ -90,21 +90,24 @@ device_name = bb_basename(path); /* http://kernel.org/doc/pending/hotplug.txt says that only * "/sys/block/..." is for block devices. "/sys/bus" etc is not. - * But since 2.6.25 block devices are also in /sys/class/block. - * We use strstr("/block/") to forestall future surprises. */ + * But since 2.6.25 block devices are also in /sys/class/block, + * we use strstr("/block/") to forestall future surprises. */ type = S_IFCHR; if (strstr(path, "/block/")) type = S_IFBLK; + /* Make path point to subsystem/device_name */ + path += sizeof("/sys/class/") - 1; + #if !ENABLE_FEATURE_MDEV_CONF mode = 0660; #else /* If we have config file, look up user settings */ parser = config_open2("/etc/mdev.conf", fopen_for_read); while (1) { - regmatch_t off[1 + 9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; + regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; int keep_matching; - char *val; + char *val, *name; struct bb_uidgid_t ugid; char *tokens[4]; # if ENABLE_FEATURE_MDEV_EXEC @@ -128,6 +131,10 @@ keep_matching = ('-' == val[0]); val += keep_matching; /* swallow leading dash */ + /* Match against either subsystem/device_name + * or device_name alone */ + name = strchr(val, '/') ? path : (char *) device_name; + /* Fields: regex uid:gid mode [alias] [cmd] */ /* 1st field: @ ... */ @@ -149,15 +156,10 @@ } else { /* ... or regex to match device name */ regex_t match; int result; - const char *dev_name_or_subsystem = device_name; - if ('/' == val[0] && subsystem) { - dev_name_or_subsystem = subsystem; - val++; - } /* Is this it? */ xregcomp(&match, val, REG_EXTENDED); - result = regexec(&match, dev_name_or_subsystem, ARRAY_SIZE(off), off, 0); + result = regexec(&match, name, ARRAY_SIZE(off), off, 0); regfree(&match); //bb_error_msg("matches:"); @@ -171,7 +173,7 @@ /* If not this device, skip rest of line */ /* (regexec returns whole pattern as "range" 0) */ if (result || off[0].rm_so - || ((int)off[0].rm_eo != (int)strlen(dev_name_or_subsystem)) + || ((int)off[0].rm_eo != (int)strlen(name)) ) { continue; /* this line doesn't match */ } @@ -214,7 +216,7 @@ if (*s++ == '%') n++; - p = alias = xzalloc(strlen(a) + n * strlen(device_name)); + p = alias = xzalloc(strlen(a) + n * strlen(name)); s = a + 1; while (*s) { *p = *s; @@ -222,7 +224,7 @@ i = (s[1] - '0'); if (i <= 9 && off[i].rm_so >= 0) { n = off[i].rm_eo - off[i].rm_so; - strncpy(p, device_name + off[i].rm_so, n); + strncpy(p, name + off[i].rm_so, n); p += n - 1; s++; } ------------------------------------------------------------------------ r26123 | vda | 2009-04-16 15:04:09 -0500 (Thu, 16 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/examples/udhcp/simple.script update example udhcpc script ------------------------------------------------------------------------ Index: examples/udhcp/simple.script =================================================================== --- examples/udhcp/simple.script (revision 26122) +++ examples/udhcp/simple.script (revision 26123) @@ -5,35 +5,42 @@ [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 RESOLV_CONF="/etc/resolv.conf" +NETMASK="" +[ -n "$subnet" ] && NETMASK="netmask $subnet" +BROADCAST="broadcast +" [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" -[ -n "$subnet" ] && NETMASK="netmask $subnet" case "$1" in deconfig) - /sbin/ifconfig $interface 0.0.0.0 + echo "Setting IP address 0.0.0.0 on $interface" + ifconfig $interface 0.0.0.0 ;; renew|bound) - /sbin/ifconfig $interface $ip $BROADCAST $NETMASK + echo "Setting IP address $ip on $interface" + ifconfig $interface $ip $NETMASK $BROADCAST if [ -n "$router" ] ; then - echo "deleting routers" + echo "Deleting routers" while route del default gw 0.0.0.0 dev $interface ; do : done metric=0 for i in $router ; do + echo "Adding router $i" route add default gw $i dev $interface metric $((metric++)) done fi - echo -n > $RESOLV_CONF - [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF + echo "Recreating $RESOLV_CONF" + echo -n > $RESOLV_CONF-$$ + [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF-$$ for i in $dns ; do - echo adding dns $i - echo nameserver $i >> $RESOLV_CONF + echo " Adding DNS server $i" + echo nameserver $i >> $RESOLV_CONF-$$ done + mv $RESOLV_CONF-$$ $RESOLV_CONF ;; esac ------------------------------------------------------------------------ r26122 | vda | 2009-04-16 07:00:15 -0500 (Thu, 16 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: add a TODO ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26121) +++ shell/hush.c (revision 26122) @@ -51,6 +51,7 @@ * TODOs: * grep for "TODO" and fix (some of them are easy) * change { and } from special chars to reserved words + * $var refs in function do not pick up values set by "var=val func" * builtins: return, ulimit * follow IFS rules more precisely, including update semantics * figure out what to do with backslash-newline ------------------------------------------------------------------------ r26121 | vda | 2009-04-16 05:59:40 -0500 (Thu, 16 Apr 2009) | 7 lines Changed paths: M /trunk/busybox/shell/hush.c A /trunk/busybox/shell/hush_test/hush-parsing/groups_and_keywords1.right A /trunk/busybox/shell/hush_test/hush-parsing/groups_and_keywords1.tests M /trunk/busybox/shell/hush_test/hush-vars/param_glob.tests hush: fix "if { echo foo; } then { echo bar; } fi" parsing function old new delta done_word 728 793 +65 parse_stream 2084 2098 +14 ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26120) +++ shell/hush.c (revision 26121) @@ -4154,6 +4154,8 @@ } return NULL; } +/* Return 0: not a keyword, 1: keyword + */ static int reserved_word(o_string *word, struct parse_context *ctx) { #if ENABLE_HUSH_CASE @@ -4163,6 +4165,8 @@ #endif const struct reserved_combo *r; + if (word->o_quoted) + return 0; r = match_reserved_word(word); if (!r) return 0; @@ -4177,13 +4181,14 @@ if (r->flag == 0) { /* '!' */ if (ctx->ctx_inverted) { /* bash doesn't accept '! ! true' */ syntax_error("! ! command"); - IF_HAS_KEYWORDS(ctx->ctx_res_w = RES_SNTX;) + ctx->ctx_res_w = RES_SNTX; } ctx->ctx_inverted = 1; return 1; } if (r->flag & FLAG_START) { struct parse_context *old; + old = xmalloc(sizeof(*old)); debug_printf_parse("push stack %p\n", old); *old = *ctx; /* physical copy */ @@ -4193,11 +4198,21 @@ syntax_error_at(word->data); ctx->ctx_res_w = RES_SNTX; return 1; + } else { + /* "{...} fi" is ok. "{...} if" is not + * Example: + * if { echo foo; } then { echo bar; } fi */ + if (ctx->command->group) + done_pipe(ctx, PIPE_SEQ); } + ctx->ctx_res_w = r->res; ctx->old_flag = r->flag; + word->o_assignment = r->assignment_flag; + if (ctx->old_flag & FLAG_END) { struct parse_context *old; + done_pipe(ctx, PIPE_SEQ); debug_printf_parse("pop stack %p\n", ctx->stack); old = ctx->stack; @@ -4213,7 +4228,6 @@ *ctx = *old; /* physical copy */ free(old); } - word->o_assignment = r->assignment_flag; return 1; } #endif @@ -4273,19 +4287,6 @@ word->o_assignment = MAYBE_ASSIGNMENT; } - if (command->group) { - /* "{ echo foo; } echo bar" - bad */ - /* NB: bash allows e.g.: - * if true; then { echo foo; } fi - * while if false; then false; fi do break; done - * and disallows: - * while if false; then false; fi; do; break; done - * TODO? */ - syntax_error_at(word->data); - debug_printf_parse("done_word return 1: syntax error, " - "groups and arglists don't mix\n"); - return 1; - } #if HAS_KEYWORDS # if ENABLE_HUSH_CASE if (ctx->ctx_dsemicolon @@ -4311,6 +4312,13 @@ } } #endif + if (command->group) { + /* "{ echo foo; } echo bar" - bad */ + syntax_error_at(word->data); + debug_printf_parse("done_word return 1: syntax error, " + "groups and arglists don't mix\n"); + return 1; + } if (word->o_quoted /* word had "xx" or 'xx' at least as part of it. */ /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */ && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL) @@ -4720,7 +4728,8 @@ #if ENABLE_HUSH_FUNCTIONS if (ch == '(' && !dest->o_quoted) { if (dest->length) - done_word(dest, ctx); + if (done_word(dest, ctx)) + return 1; if (!command->argv) goto skip; /* (... */ if (command->argv[1]) { /* word word ... (... */ @@ -4778,10 +4787,10 @@ #endif /* empty ()/{} or parse error? */ if (!pipe_list || pipe_list == ERR_PTR) { + /* parse_stream already emitted error msg */ #if !BB_MMU free(as_string); #endif - syntax_error(NULL); debug_printf_parse("parse_group return 1: " "parse_stream returned %p\n", pipe_list); return 1; Index: shell/hush_test/hush-vars/param_glob.tests =================================================================== --- shell/hush_test/hush-vars/param_glob.tests (revision 26120) +++ shell/hush_test/hush-vars/param_glob.tests (revision 26121) @@ -1,5 +1,5 @@ if test $# = 0; then - #BUG in builtin_exec! will glob param! + # UNFIXED BUG in builtin_exec! will glob param! #exec "$THIS_SH" "$0" 'param_glob.t*' "$THIS_SH" "$0" 'param_glob.t*' exit Index: shell/hush_test/hush-parsing/groups_and_keywords1.right =================================================================== --- shell/hush_test/hush-parsing/groups_and_keywords1.right (revision 0) +++ shell/hush_test/hush-parsing/groups_and_keywords1.right (revision 26121) @@ -0,0 +1,11 @@ +Semicolons after } can be omitted 1: +foo +bar +Semicolons after } can be omitted 2: +foo +bar +Semicolons after fi can be omitted: +foo +bar +baz +Done:0 Index: shell/hush_test/hush-parsing/groups_and_keywords1.tests =================================================================== --- shell/hush_test/hush-parsing/groups_and_keywords1.tests (revision 0) +++ shell/hush_test/hush-parsing/groups_and_keywords1.tests (revision 26121) @@ -0,0 +1,10 @@ +echo "Semicolons after } can be omitted 1:" +if { echo foo; } then { echo bar; } fi + +echo "Semicolons after } can be omitted 2:" +while { echo foo; } do { echo bar; break; } done + +echo "Semicolons after fi can be omitted:" +while if echo foo; then echo bar; fi do echo baz; break; done + +echo Done:$? Property changes on: shell/hush_test/hush-parsing/groups_and_keywords1.tests ___________________________________________________________________ Name: svn:executable + * ------------------------------------------------------------------------ r26120 | vda | 2009-04-15 18:29:44 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: stop ignoring ^Z in child shells ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26119) +++ shell/hush.c (revision 26120) @@ -2276,15 +2276,28 @@ static void reset_traps_to_defaults(void) { + enum { + JOBSIGS = (1 << SIGTTIN) | (1 << SIGTTOU) | (1 << SIGTSTP) + }; unsigned sig; - int dirty; - if (!G.traps) + if (!G.traps && !(G.non_DFL_mask & JOBSIGS)) return; - dirty = 0; - for (sig = 0; sig < NSIG; sig++) { - if (!G.traps[sig]) + + /* This function is always called in a child shell. + * Child shells are not interactive. + * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling. + * Testcase: (while :; do :; done) + ^Z should background. + */ + G.non_DFL_mask &= ~JOBSIGS; + sigdelset(&G.blocked_set, SIGTTIN); + sigdelset(&G.blocked_set, SIGTTOU); + sigdelset(&G.blocked_set, SIGTSTP); + + if (G.traps) for (sig = 0; sig < NSIG; sig++) { + if (!G.traps[sig]) { continue; + } free(G.traps[sig]); G.traps[sig] = NULL; /* There is no signal for 0 (EXIT) */ @@ -2296,10 +2309,8 @@ if (sig < 32 && (G.non_DFL_mask & (1 << sig))) continue; sigdelset(&G.blocked_set, sig); - dirty = 1; } - if (dirty) - sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); + sigprocmask(SIG_SETMASK, &G.blocked_set, NULL); } #else /* !BB_MMU */ ------------------------------------------------------------------------ r26119 | vda | 2009-04-15 18:29:00 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: remove old disabled ^Z handling ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26118) +++ shell/hush.c (revision 26119) @@ -56,7 +56,6 @@ * figure out what to do with backslash-newline * continuation lines, both explicit and implicit - done? * SIGHUP handling - * ^Z handling (and explain it in comments for mere humans) * separate job control from interactiveness * (testcase: booting with init=/bin/hush does not show prompt (2009-04)) * @@ -432,7 +431,6 @@ int last_jobid; struct pipe *job_list; struct pipe *toplevel_list; -//// smallint ctrl_z_flag; #endif smallint flag_SIGINT; #if ENABLE_HUSH_LOOPS @@ -474,12 +472,6 @@ int debug_indent; #endif char user_input_buf[ENABLE_FEATURE_EDITING ? BUFSIZ : 2]; -#if ENABLE_FEATURE_SH_STANDALONE - struct nofork_save_area nofork_save; -#endif -#if ENABLE_HUSH_JOB - sigjmp_buf toplevel_jb; -#endif }; #define G (*ptr_to_globals) /* Not #defining name to G.name - this quickly gets unwieldy @@ -977,13 +969,14 @@ * SIGHUP (interactive): * send SIGCONT to stopped jobs, send SIGHUP to all jobs and exit * SIGTTIN, SIGTTOU, SIGTSTP (if job control is on): ignore - * (note that ^Z is handled not by trapping SIGTSTP, but by seeing - * that all pipe members are stopped) (right?) + * Note that ^Z is handled not by trapping SIGTSTP, but by seeing + * that all pipe members are stopped. Try this in bash: + * while :; do :; done - ^Z does not background it + * (while :; do :; done) - ^Z backgrounds it * SIGINT (interactive): wait for last pipe, ignore the rest * of the command line, show prompt. NB: ^C does not send SIGINT * to interactive shell while shell is waiting for a pipe, * since shell is bg'ed (is not in foreground process group). - * (check/expand this) * Example 1: this waits 5 sec, but does not execute ls: * "echo $$; sleep 5; ls -l" + "kill -INT " * Example 2: this does not wait and does not execute ls: @@ -3411,12 +3404,11 @@ if (i >= 0 && APPLET_IS_NOFORK(i)) { rcode = setup_redirects(command, squirrel); if (rcode == 0) { - save_nofork_data(&G.nofork_save); new_env = expand_assignments(argv, command->assignment_cnt); old_env = putenv_all_and_save_old(new_env); debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]); - rcode = run_nofork_applet_prime(&G.nofork_save, i, argv_expanded); + rcode = run_nofork_applet(i, argv_expanded); } goto clean_up_and_ret; } @@ -3643,7 +3635,7 @@ smallint last_rword; /* ditto */ #endif - debug_printf_exec("run_list start lvl %d\n", G.run_list_level + 1); + debug_printf_exec("run_list start lvl %d\n", G.run_list_level); debug_enter(); #if ENABLE_HUSH_LOOPS @@ -3677,51 +3669,9 @@ * in order to return, no direct "return" statements please. * This helps to ensure that no memory is leaked. */ -////TODO: ctrl-Z handling needs re-thinking and re-testing - #if ENABLE_HUSH_JOB - /* Example of nested list: "while true; do { sleep 1 | exit 2; } done". - * We are saving state before entering outermost list ("while...done") - * so that ctrl-Z will correctly background _entire_ outermost list, - * not just a part of it (like "sleep 1 | exit 2") */ - if (++G.run_list_level == 1 && G_interactive_fd) { - if (sigsetjmp(G.toplevel_jb, 1)) { - /* ctrl-Z forked and we are parent; or ctrl-C. - * Sighandler has longjmped us here */ - signal(SIGINT, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - /* Restore level (we can be coming from deep inside - * nested levels) */ - G.run_list_level = 1; -#if ENABLE_FEATURE_SH_STANDALONE - if (G.nofork_save.saved) { /* if save area is valid */ - debug_printf_jobs("exiting nofork early\n"); - restore_nofork_data(&G.nofork_save); - } + G.run_list_level++; #endif -//// if (G.ctrl_z_flag) { -//// /* ctrl-Z has forked and stored pid of the child in pi->pid. -//// * Remember this child as background job */ -//// insert_bg_job(pi); -//// } else { - /* ctrl-C. We just stop doing whatever we were doing */ - bb_putchar('\n'); -//// } - USE_HUSH_LOOPS(loop_top = NULL;) - USE_HUSH_LOOPS(G.depth_of_loop = 0;) - rcode = 0; - goto ret; - } -//// /* ctrl-Z handler will store pid etc in pi */ -//// G.toplevel_list = pi; -//// G.ctrl_z_flag = 0; -#if ENABLE_FEATURE_SH_STANDALONE - G.nofork_save.saved = 0; /* in case we will run a nofork later */ -#endif -//// signal_SA_RESTART_empty_mask(SIGTSTP, handler_ctrl_z); -//// signal(SIGINT, handler_ctrl_c); - } -#endif /* JOB */ #if HAS_KEYWORDS rword = RES_NONE; @@ -3967,18 +3917,7 @@ } /* for (pi) */ #if ENABLE_HUSH_JOB -//// if (G.ctrl_z_flag) { -//// /* ctrl-Z forked somewhere in the past, we are the child, -//// * and now we completed running the list. Exit. */ -//////TODO: _exit? -//// exit(rcode); -//// } - ret: G.run_list_level--; -//// if (!G.run_list_level && G_interactive_fd) { -//// signal(SIGTSTP, SIG_IGN); -//// signal(SIGINT, SIG_IGN); -//// } #endif #if ENABLE_HUSH_LOOPS if (loop_top) ------------------------------------------------------------------------ r26118 | vda | 2009-04-15 16:58:14 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: fix heredoc_huge.tests broken in last commits ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26117) +++ shell/hush.c (revision 26118) @@ -2461,11 +2461,15 @@ * for the unsuspecting parent process. Child creates a grandchild * and exits before parent execs the process which consumes heredoc * (that exec happens after we return from this function) */ +#if !BB_MMU + to_free = NULL; +#endif pid = vfork(); if (pid < 0) bb_perror_msg_and_die("vfork"); if (pid == 0) { /* child */ + disable_restore_tty_pgrp_on_exit(); pid = BB_MMU ? fork() : vfork(); if (pid < 0) bb_perror_msg_and_die(BB_MMU ? "fork" : "vfork"); @@ -2478,7 +2482,6 @@ _exit(0); #else /* Delegate blocking writes to another process */ - disable_restore_tty_pgrp_on_exit(); xmove_fd(pair.wr, STDOUT_FILENO); re_execute_shell(&to_free, heredoc, NULL, NULL); #endif ------------------------------------------------------------------------ r26117 | vda | 2009-04-15 16:49:48 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/shell/hush.c hush: remove TODO comment itself :) ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26116) +++ shell/hush.c (revision 26117) @@ -147,8 +147,7 @@ static const char hush_version_str[] ALIGN1 = "HUSH_VERSION="BB_VER; /* This supports saving pointers malloced in vfork child, - * to be freed in the parent. One pointer is saved in - * G.argv_from_re_execing global var instead. TODO: unify. + * to be freed in the parent. */ #if !BB_MMU typedef struct nommu_save_t { ------------------------------------------------------------------------ r26116 | vda | 2009-04-15 16:48:23 -0500 (Wed, 15 Apr 2009) | 13 lines Changed paths: M /trunk/busybox/shell/hush.c hush: deal with a TODO: move argv_from_re_execing out of globals function old new delta generate_stream_from_string 156 165 +9 setup_heredoc 312 320 +8 re_execute_shell 387 391 +4 pseudo_exec_argv 129 133 +4 run_pipe 1790 1783 -7 clean_up_after_re_execute 30 - -30 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 4/1 up/down: 25/-37) Total: -12 bytes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26115) +++ shell/hush.c (revision 26116) @@ -155,6 +155,7 @@ char **new_env; char **old_env; char **argv; + char **argv_from_re_execing; } nommu_save_t; #endif @@ -449,7 +450,6 @@ char **global_argv; #if !BB_MMU char *argv0_for_re_execing; - char **argv_from_re_execing; #endif #if ENABLE_HUSH_LOOPS unsigned depth_break_continue; @@ -2280,10 +2280,8 @@ #if BB_MMU /* never called */ -void re_execute_shell(const char *s, char *argv0, char **argv); +void re_execute_shell(char ***to_free, const char *s, char *argv0, char **argv); -#define clean_up_after_re_execute() ((void)0) - static void reset_traps_to_defaults(void) { unsigned sig; @@ -2314,8 +2312,8 @@ #else /* !BB_MMU */ -static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) NORETURN; -static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) +static void re_execute_shell(char ***to_free, const char *s, char *g_argv0, char **g_argv) NORETURN; +static void re_execute_shell(char ***to_free, const char *s, char *g_argv0, char **g_argv) { char param_buf[sizeof("-$%x:%x:%x:%x") + sizeof(unsigned) * 4]; char *heredoc_argv[4]; @@ -2357,7 +2355,7 @@ pp = g_argv; while (*pp++) cnt++; - G.argv_from_re_execing = argv = pp = xzalloc(sizeof(argv[0]) * cnt); + *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt); *pp++ = (char *) G.argv0_for_re_execing; *pp++ = param_buf; for (cur = G.top_var; cur; cur = cur->next) { @@ -2415,16 +2413,6 @@ xfunc_error_retval = 127; bb_error_msg_and_die("can't re-execute the shell"); } - -static void clean_up_after_re_execute(void) -{ - char **pp = G.argv_from_re_execing; - if (pp) { - /* Must match re_execute_shell's allocations (if any) */ - free(pp); - G.argv_from_re_execing = NULL; - } -} #endif /* !BB_MMU */ @@ -2436,6 +2424,9 @@ /* the _body_ of heredoc (misleading field name) */ const char *heredoc = redir->rd_filename; char *expanded; +#if !BB_MMU + char **to_free; +#endif expanded = NULL; if (!(redir->rd_dup & HEREDOC_QUOTED)) { @@ -2490,12 +2481,14 @@ /* Delegate blocking writes to another process */ disable_restore_tty_pgrp_on_exit(); xmove_fd(pair.wr, STDOUT_FILENO); - re_execute_shell(heredoc, NULL, NULL); + re_execute_shell(&to_free, heredoc, NULL, NULL); #endif } /* parent */ enable_restore_tty_pgrp_on_exit(); - clean_up_after_re_execute(); +#if !BB_MMU + free(to_free); +#endif close(pair.wr); free(expanded); wait(NULL); /* wait till child has died */ @@ -2742,8 +2735,16 @@ return funcp; } -static void exec_function(const struct function *funcp, char **argv) NORETURN; -static void exec_function(const struct function *funcp, char **argv) +#if BB_MMU +#define exec_function(nommu_save, funcp, argv) \ + exec_function(funcp, argv) +#endif +static void exec_function(nommu_save_t *nommu_save, + const struct function *funcp, + char **argv) NORETURN; +static void exec_function(nommu_save_t *nommu_save, + const struct function *funcp, + char **argv) { # if BB_MMU int n = 1; @@ -2758,7 +2759,10 @@ fflush(NULL); _exit(n); # else - re_execute_shell(funcp->body_as_string, G.global_argv[0], argv + 1); + re_execute_shell(&nommu_save->argv_from_re_execing, + funcp->body_as_string, + G.global_argv[0], + argv + 1); # endif } @@ -2889,7 +2893,7 @@ { const struct function *funcp = find_function(argv[0]); if (funcp) { - exec_function(funcp, argv); + exec_function(nommu_save, funcp, argv); } } #endif @@ -2955,7 +2959,8 @@ * since this process is about to exit */ _exit(rcode); #else - re_execute_shell(command->group_as_string, + re_execute_shell(&nommu_save->argv_from_re_execing, + command->group_as_string, G.global_argv[0], G.global_argv + 1); #endif @@ -3432,6 +3437,7 @@ nommu_save.new_env = NULL; nommu_save.old_env = NULL; nommu_save.argv = NULL; + nommu_save.argv_from_re_execing = NULL; #endif command = &(pi->cmds[i]); if (command->argv) { @@ -3489,8 +3495,8 @@ enable_restore_tty_pgrp_on_exit(); #if !BB_MMU /* Clean up after vforked child */ - clean_up_after_re_execute(); free(nommu_save.argv); + free(nommu_save.argv_from_re_execing); free_strings_and_unsetenv(nommu_save.new_env, 1); putenv_all(nommu_save.old_env); /* Free the pointers, but the strings themselves @@ -4657,6 +4663,9 @@ { FILE *pf; int pid, channel[2]; +#if !BB_MMU + char **to_free; +#endif xpipe(channel); pid = BB_MMU ? fork() : vfork(); @@ -4688,7 +4697,8 @@ * huge=`cat BIG` # was blocking here forever * echo OK */ - re_execute_shell(s, + re_execute_shell(&to_free, + s, G.global_argv[0], G.global_argv + 1); #endif @@ -4696,7 +4706,9 @@ /* parent */ enable_restore_tty_pgrp_on_exit(); - clean_up_after_re_execute(); +#if !BB_MMU + free(to_free); +#endif close(channel[1]); pf = fdopen(channel[0], "r"); return pf; ------------------------------------------------------------------------ r26109 | vda | 2009-04-15 08:04:52 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/Makefile Start 1.15.x development ------------------------------------------------------------------------ Index: Makefile =================================================================== --- Makefile (revision 26108) +++ Makefile (revision 26109) @@ -1,7 +1,7 @@ VERSION = 1 -PATCHLEVEL = 14 +PATCHLEVEL = 15 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = .svn NAME = Unnamed # *DOCUMENTATION* ------------------------------------------------------------------------ r26106 | vda | 2009-04-15 06:55:27 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/docs/busybox.net/news.html website: another tweak ------------------------------------------------------------------------ Index: docs/busybox.net/news.html =================================================================== --- docs/busybox.net/news.html (revision 26105) +++ docs/busybox.net/news.html (revision 26106) @@ -82,7 +82,7 @@ brctl: fix compilation on 2.4.x kernels chat: treat timeout more correctly chat: recognize RECORD directive -cksum, printenv: report errors via exitcode +cksum, head, printenv: report errors via exitcode cpio: add -p, -0 and -L options crond, crontab: make cron directory location configurable crond: correct more of logfile to 0666 (as usual, umask allows user to remove unwanted bits) @@ -90,14 +90,12 @@dc: fix the "base 2" patch omission of base not being set depmod: accept and ignore -r. Linux kernel build needs this depmod: fix -b option. By timo.teras AT iki.fi -udhcpd, dumpleases: write and use 64-bit current time in lease file. Without it, determination of remaining lease time is unreliable -udhcpd: remember hostnames of clients -dumpleases: fix -a option -dumpleases: show hostnames udhcpc: fix a problem where we don't open listening socket fast enough udhcpc: stop filtering environment passed to the script -udhcpd: add code which rejects lease files with suspicious or old timestamp -udhcpd: disable opton to have absolute lease times in lease file (that does not work with dumpleases) +udhcpd: disable option to have absolute lease times in lease file (that does not work with dumpleases) +udhcpd: write 64-bit current time in lease file. Without it, determination of remaining lease time is unreliable +udhcpd: remember hostnames of clients +dumpleases: fix -a option, use recorded current time in lease file, show hostnames dnsd: fix a number of bugs. Ideas by Ming-Ching Tiew (mctiew AT yahoo.com) dpkg: better and shorter code to compare versions. Taken from "official" dpkg by Eugene T. Bordenkircher (eugebo AT gmail.com) du: fix "du /dir /dir" case @@ -108,7 +106,6 @@getty: make speed 0 mean "don't change speed", stop using non-portable way of setting speeds grep: support -z gzip: fix gzip -dc bug caused by using stale getopt state -head: report file open errors with exitcode 1 (was happily returning 0) httpd: set $HOST to Host: header value. By Tobias Poschwatta (tp AT fonz.de) ifupdown: allow options to udhcpc to be configurable from .config init: do not eat last char in messages; do not print duplicate "init:" prefix to syslog ------------------------------------------------------------------------ r26105 | vda | 2009-04-15 06:51:18 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/docs/busybox.net/news.html website: yet another small tweak ------------------------------------------------------------------------ Index: docs/busybox.net/news.html =================================================================== --- docs/busybox.net/news.html (revision 26104) +++ docs/busybox.net/news.html (revision 26105) @@ -68,14 +68,13 @@util-linux/volumeid: abort early on read failures. Should help with probing missing fdd's util-linux/volumeid: fix bug 249 "findfs finds the wrong partition" adduser: allow adding to group 0; don't _create_ /etc/shadow, only append data if it exists -ash: fix mishandled ^C +ash: fix mishandled ^C and SIGINT (several cases) ash: fix "ash -c 'exec 1>&0'" complaining that fd 0 is busy ash: fix $IFS handling in read. Closes bug 235 -ash: fix a case where we close wrong descriptor +ash: fix a case where we were closing wrong descriptor ash: fix bad interaction between ash -c '....&' and bash compat ash: fix miscalculation of memory needed for eval tree. Found by Timo Teras (timo.teras AT iki.fi) ash: make dot command search current directory first, as bash does -ash: make evaltree save/restore int suppression depth. Hopefully this fixes bug 189 ash: printf builtin with no arguments should not exit awk: fix long field separators case. By Ian Wienand (ianw AT vmware.com) awk: in BEGIN section $0 should be "", not "0" ------------------------------------------------------------------------ r26104 | vda | 2009-04-15 06:48:25 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/docs/busybox.net/news.html website: another tiny tweak ------------------------------------------------------------------------ Index: docs/busybox.net/news.html =================================================================== --- docs/busybox.net/news.html (revision 26103) +++ docs/busybox.net/news.html (revision 26104) @@ -106,7 +106,7 @@expand, unexpand: fix incorrect expansion in some cases expr: a bit more robust handling of regexps with groups. Closes bug 87 find: support --mindepth -getty: fix handling of speed 0; stop using non-portable way of setting speeds +getty: make speed 0 mean "don't change speed", stop using non-portable way of setting speeds grep: support -z gzip: fix gzip -dc bug caused by using stale getopt state head: report file open errors with exitcode 1 (was happily returning 0) ------------------------------------------------------------------------ r26103 | vda | 2009-04-15 06:11:19 -0500 (Wed, 15 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/docs/busybox.net/news.html website: textual fixes in 1.14.0 announcement text ------------------------------------------------------------------------ Index: docs/busybox.net/news.html =================================================================== --- docs/busybox.net/news.html (revision 26102) +++ docs/busybox.net/news.html (revision 26103) @@ -44,10 +44,10 @@New applets:
@@ -55,16 +55,18 @@
- flash_eraseall: by Sebastian Andrzej Siewior (bigeasy AT linutronix.de)
-- acpid,mkdosfs (aka mkfs.vfat),tunctl: by Vladimir
-- ftpd: by Adam Tkac
+- acpid, mkdosfs, tunctl: by Vladimir
+- ftpd: by Adam Tkac (vonsch AT gmail.com)
- timeout: by Roberto Foglietta
-- ionice: adapted from Linux kernel' example by Walter Harms
+- ionice: adapted from Linux kernel example by Walter Harms
- mkpasswd: synonym to cryptpw. mkpasswd is in Debian, OTOH cryptpw was added to busybox earlier. Trying to make both camps happy by making those two applets just aliases. They are command-line compatible
lash and msh are deprecated, please migrate to hush. -
hush had many, many fixes and features added: here documents, arithmetic evaluation, function support, and all this works on NOMMU too, safely: 100kb-sized `command` and heredocs. Here document support, arithmetic evaluation, improved ${var} ops, other fixes are by Mike Frysinger (vapier AT gentoo.org). +
hush had many, many fixes and features added: here documents, arithmetic evaluation, function support, and all this works on NOMMU too, safely, including 100kb-sized `command` and here documents. Here document support, arithmetic evaluation, improved ${var} operations, other fixes are by Mike Frysinger (vapier AT gentoo.org).
Other changes:
------------------------------------------------------------------------ r26101 | vda | 2009-04-14 21:13:14 -0500 (Tue, 14 Apr 2009) | 4 lines Changed paths: M /trunk/busybox/Makefile M /trunk/busybox/docs/busybox.net/news.html M /trunk/busybox/libbb/Kbuild M /trunk/busybox/scripts/defconfig website: announce 1.14.0 and 1.13.4 Makefile: bump version to 1.14.0 ------------------------------------------------------------------------ Index: scripts/defconfig =================================================================== --- scripts/defconfig (revision 26100) +++ scripts/defconfig (revision 26101) @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.14.0.svn -# Mon Apr 13 16:22:36 2009 +# Busybox version: 1.14.0 +# Wed Apr 15 04:12:17 2009 # CONFIG_HAVE_DOT_CONFIG=y Index: docs/busybox.net/news.html =================================================================== --- docs/busybox.net/news.html (revision 26100) +++ docs/busybox.net/news.html (revision 26101) @@ -22,6 +22,166 @@ +
- libbb: unify concurrent-safe update of /etc/{passwd,group,[g]shadow}. By Tito (farmatito AT tiscali.it)
-- libbb/sha1/256/512: major code shrink
+- libbb/sha{1,256,512}: major code shrink
- libbb/lineedit: make history saving/loading concurrent-safe
- libbb: shrink linked list ops. By xmaks AT email.cz
-- libbb: str2sockaddr shuld accept [IPv6] addr without port - wget 'ftp://[::1]/file' needs that to work
+- libbb: str2sockaddr should accept [IPv6] addr without port - wget 'ftp://[::1]/file' needs that to work
- libbb: make bb_info_msg do atomic, unbuffered writes
+- util-linux/volumeid: abort early on read failures. Should help with probing missing fdd's
+- util-linux/volumeid: fix bug 249 "findfs finds the wrong partition"
- adduser: allow adding to group 0; don't _create_ /etc/shadow, only append data if it exists
- ash: fix mishandled ^C
- ash: fix "ash -c 'exec 1>&0'" complaining that fd 0 is busy
@@ -72,7 +74,6 @@- ash: fix a case where we close wrong descriptor
- ash: fix bad interaction between ash -c '....&' and bash compat
- ash: fix miscalculation of memory needed for eval tree. Found by Timo Teras (timo.teras AT iki.fi)
-- ash: in dotrap(), do not clear gotsig[] for SIGINT if there is no handler for it, otherwise raise interrupt gets confused later
- ash: make dot command search current directory first, as bash does
- ash: make evaltree save/restore int suppression depth. Hopefully this fixes bug 189
- ash: printf builtin with no arguments should not exit
@@ -84,16 +85,16 @@- chat: recognize RECORD directive
- cksum, printenv: report errors via exitcode
- cpio: add -p, -0 and -L options
-- crond,crontab: make cron directory location configurable
+- crond, crontab: make cron directory location configurable
- crond: correct more of logfile to 0666 (as usual, umask allows user to remove unwanted bits)
- crond: put tasks in separate process groups
- dc: fix the "base 2" patch omission of base not being set
- depmod: accept and ignore -r. Linux kernel build needs this
- depmod: fix -b option. By timo.teras AT iki.fi
-- udhcpd,dumpleases: write and use 64-bit current time in lease file. without it, determination of remaining lease time is unreliable
-- udhcpd: remember and record hostnames
-- dhcprelay: fix usage text. Simplify and make code more readable
-- dumpleases: fix -a option; show hostnames
+- udhcpd, dumpleases: write and use 64-bit current time in lease file. Without it, determination of remaining lease time is unreliable
+- udhcpd: remember hostnames of clients
+- dumpleases: fix -a option
+- dumpleases: show hostnames
- udhcpc: fix a problem where we don't open listening socket fast enough
- udhcpc: stop filtering environment passed to the script
- udhcpd: add code which rejects lease files with suspicious or old timestamp
@@ -102,7 +103,7 @@- dpkg: better and shorter code to compare versions. Taken from "official" dpkg by Eugene T. Bordenkircher (eugebo AT gmail.com)
- du: fix "du /dir /dir" case
- env: support -uVAR=VAL
-- expand: fix incorrect expansion exactly on tab boundary; shrink the code
+- expand, unexpand: fix incorrect expansion in some cases
- expr: a bit more robust handling of regexps with groups. Closes bug 87
- find: support --mindepth
- getty: fix handling of speed 0; stop using non-portable way of setting speeds
@@ -119,7 +120,6 @@- init: test for vt terminal with VT_OPENQRY, assume that anything else is TERM=vt102, not TERM=linux. Closes bug 195
- inotifyd: add x, o, and u events
- inotifyd: fix buffer overflow and "unreaped zombies" problem
-- inotifyd: exit if x event happened for all files
- inotifyd: conserve resourses by closing unused inotify descriptors
- insmod/modprobe: do not pass NULL to kernel as module parameter
- ip: in "ip rule add from all table 1", "all" is taken as 0.0.0.0/32, whereas "any" and "default" would be 0.0.0.0/0. They must be all 0.0.0.0/0. Closes bug 57
@@ -134,14 +134,11 @@- mdev: ignore events with "$SUBSYSTEM" == "firmware" && "$ACTION" == "remove"
- mdev: provide $SUBSYSTEM. By Vladimir
- modprobe/insmod for 2.4: support compressed modules. By Guenter (lists AT gknw.net)
-- modprobe: emit "can't open 'modules.dep': (errno)" instead of "module not found"
- modprobe: rework/speedup by Timo Teras (timo.teras AT iki.fi)
- modutils-24: fix bad interaction of xzalloc with xrealloc_vector
-- mount: support "-O option"
-- mount: stop trying to mount swap partitions
-- mount: fix CIFS support
+- mount: support "-O option", stop trying to mount swap partitions, fix CIFS support
- mountpoint: add -n option. By Vladimir
-- nslookup: allow usage of IPv6 addresses or hostnames for DNS server name; allow for port specification. Tested to work: "nslookup google.com [::1]:5353". glibc + IPv6 address of DNS server still does not work
+- nslookup: allow usage of IPv6 addresses or hostnames for DNS server name; allow for port specification. Tested to work on uclibc svn: "nslookup google.com [::1]:5353". glibc + IPv6 address of DNS server still does not work
- popmaildir: fix several grave bugs with using memory past end of malloc block
- printf: fix 1.12.0 breakage (from %*d fix), it was misinterpreting "*"
- printf: make integer format strings print long long-sized values
@@ -154,7 +151,7 @@- sysctl: fix another corner case with "dots and slashes"
- sysctl: fix broken -p [file]. Closes bug 231
- sysctl: support recursing if name is a directory: "sysctl net.ipv4.conf". Patch by xmaks AT email.cz
-- syslogd: comment out file locking; make signal handling syncronous
+- syslogd: make signal handling syncronous
- syslogd: create logfile with 0666 (affected by umask as usual), not 0600
- tail: fix tail +N syntax not working. Closes bug 221
- tar: do not change new tarfile's mode, GNU tar doesn't do it
@@ -164,21 +161,15 @@- tftp: when we infer local name from remote (-r [/]path/path/file), strip path. This mimics wget and is generally more intuitive
- timeout: fix parsing of -t NUM on MMU
- top: make it work again on 2.4 kernels. Closes bug 125
-- tr: fix overflow in expand and complement, fix stop after [:class:]
-- tr: support -C as synonym to -c
-- tr: support [:xdigit:], fix handling of ranges and [x]'s
+- tr: fix overflow in expand and complement, fix stop after [:class:], fix handling of ranges and [x]'s
+- tr: support -C as synonym to -c, support [:xdigit:]
- traceroute: rewrite. Do not emit raw IP packets, instead send UDP or ICMP packets and rely on the kernel to form IP headers, select source IP and interface
-- uname: add support for -i and -o, fix printing of unknown -p value with -a option
-- uname: support long options
-- unexpand: fix incorrect expansion
+- uname: add support for -i and -o, fix printing of unknown -p value with -a option, support long options
- unzip: fix thinko with le/be conv and size. Closes bug 129
- vi: fix several instances of major goof: when text grows, text[] might get reallocated! We were keeping around pointers to old place
- vi: speedup and code shrink. By Walter Harms
-- volume_id: abort early on read failures. Should help with probing missing fdd's
-- volumeid: fix bug 249 "findfs finds the wrong partition"
- wget: --post-data support. By Harald Kuthe (harald-tuxbox AT arcor.de)
-- wget: fix --header handling
-- wget: more robust EINTR detection
+- wget: fix --header handling, more robust EINTR detection
15 April 2009 -- BusyBox 1.14.0 (unstable), BusyBox 1.13.4 (stable) + BusyBox 1.14.0. + (svn, + patches, + how to add a patch)
+BusyBox 1.13.4. + (svn, + patches, + how to add a patch)
+ +Sizes of busybox-1.13.4 and busybox-1.14.0 (with equivalent config, static uclibc build):
+ text data bss dec hex filename + 785501 483 7036 793020 c19bc busybox.1.13.4/busybox + 788380 467 6960 795807 c249f busybox.1.14.0/busybox + 15361 0 0 15361 3c01 busybox.1.13.4/shell/hush.o + 20724 0 0 20724 50f4 busybox.1.14.0/shell/hush.o ++Most of growth is in hush. The rest shrank a bit. + +
New applets: +
+
+ +- flash_eraseall: by Sebastian Andrzej Siewior (bigeasy AT linutronix.de)
+- acpid,mkdosfs (aka mkfs.vfat),tunctl: by Vladimir
+- ftpd: by Adam Tkac
+- timeout: by Roberto Foglietta
+- ionice: adapted from Linux kernel' example by Walter Harms
+- mkpasswd: synonym to cryptpw. mkpasswd is in Debian, OTOH cryptpw was added to busybox earlier. Trying to make both camps happy by making those two applets just aliases. They are command-line compatible
+Changes since previous release: + +
lash and msh are deprecated, please migrate to hush. + +
hush had many, many fixes and features added: here documents, arithmetic evaluation, function support, and all this works on NOMMU too, safely: 100kb-sized `command` and heredocs. Here document support, arithmetic evaluation, improved ${var} ops, other fixes are by Mike Frysinger (vapier AT gentoo.org). + +
Other changes: +
+
+ +- libbb: unify concurrent-safe update of /etc/{passwd,group,[g]shadow}. By Tito (farmatito AT tiscali.it)
+- libbb/sha1/256/512: major code shrink
+- libbb/lineedit: make history saving/loading concurrent-safe
+- libbb: shrink linked list ops. By xmaks AT email.cz
+- libbb: str2sockaddr shuld accept [IPv6] addr without port - wget 'ftp://[::1]/file' needs that to work
+- libbb: make bb_info_msg do atomic, unbuffered writes
+- adduser: allow adding to group 0; don't _create_ /etc/shadow, only append data if it exists
+- ash: fix mishandled ^C
+- ash: fix "ash -c 'exec 1>&0'" complaining that fd 0 is busy
+- ash: fix $IFS handling in read. Closes bug 235
+- ash: fix a case where we close wrong descriptor
+- ash: fix bad interaction between ash -c '....&' and bash compat
+- ash: fix miscalculation of memory needed for eval tree. Found by Timo Teras (timo.teras AT iki.fi)
+- ash: in dotrap(), do not clear gotsig[] for SIGINT if there is no handler for it, otherwise raise interrupt gets confused later
+- ash: make dot command search current directory first, as bash does
+- ash: make evaltree save/restore int suppression depth. Hopefully this fixes bug 189
+- ash: printf builtin with no arguments should not exit
+- awk: fix long field separators case. By Ian Wienand (ianw AT vmware.com)
+- awk: in BEGIN section $0 should be "", not "0"
+- awk: make "struct global" hack more robust wrt alignment. Closes bug 131
+- brctl: fix compilation on 2.4.x kernels
+- chat: treat timeout more correctly
+- chat: recognize RECORD directive
+- cksum, printenv: report errors via exitcode
+- cpio: add -p, -0 and -L options
+- crond,crontab: make cron directory location configurable
+- crond: correct more of logfile to 0666 (as usual, umask allows user to remove unwanted bits)
+- crond: put tasks in separate process groups
+- dc: fix the "base 2" patch omission of base not being set
+- depmod: accept and ignore -r. Linux kernel build needs this
+- depmod: fix -b option. By timo.teras AT iki.fi
+- udhcpd,dumpleases: write and use 64-bit current time in lease file. without it, determination of remaining lease time is unreliable
+- udhcpd: remember and record hostnames
+- dhcprelay: fix usage text. Simplify and make code more readable
+- dumpleases: fix -a option; show hostnames
+- udhcpc: fix a problem where we don't open listening socket fast enough
+- udhcpc: stop filtering environment passed to the script
+- udhcpd: add code which rejects lease files with suspicious or old timestamp
+- udhcpd: disable opton to have absolute lease times in lease file (that does not work with dumpleases)
+- dnsd: fix a number of bugs. Ideas by Ming-Ching Tiew (mctiew AT yahoo.com)
+- dpkg: better and shorter code to compare versions. Taken from "official" dpkg by Eugene T. Bordenkircher (eugebo AT gmail.com)
+- du: fix "du /dir /dir" case
+- env: support -uVAR=VAL
+- expand: fix incorrect expansion exactly on tab boundary; shrink the code
+- expr: a bit more robust handling of regexps with groups. Closes bug 87
+- find: support --mindepth
+- getty: fix handling of speed 0; stop using non-portable way of setting speeds
+- grep: support -z
+- gzip: fix gzip -dc bug caused by using stale getopt state
+- head: report file open errors with exitcode 1 (was happily returning 0)
+- httpd: set $HOST to Host: header value. By Tobias Poschwatta (tp AT fonz.de)
+- ifupdown: allow options to udhcpc to be configurable from .config
+- init: do not eat last char in messages; do not print duplicate "init:" prefix to syslog
+- init: fix a bug where on reload order of entries might be wrong
+- init: major improvement in documentation and signal handling. Lots of nasty, but hard to trip, races are fixed
+- init: reinstate proper handling of !ENABLE_FEATURE_USE_INITTAB
+- init: remove wait loop on restart, it may be dangerous
+- init: test for vt terminal with VT_OPENQRY, assume that anything else is TERM=vt102, not TERM=linux. Closes bug 195
+- inotifyd: add x, o, and u events
+- inotifyd: fix buffer overflow and "unreaped zombies" problem
+- inotifyd: exit if x event happened for all files
+- inotifyd: conserve resourses by closing unused inotify descriptors
+- insmod/modprobe: do not pass NULL to kernel as module parameter
+- ip: in "ip rule add from all table 1", "all" is taken as 0.0.0.0/32, whereas "any" and "default" would be 0.0.0.0/0. They must be all 0.0.0.0/0. Closes bug 57
+- iproute: fix ipXXX utilities trying to parse their applet name as their 1st parameter
+- klogctl: fix a problem where we don't terminate read data with '\0' and then misinterpret it
+- ls: do not follow links with -s. Closes bug 33
+- ls: implement -Q and -g (-g was accepted but ignored)
+- ls: make readlink error to not disrupt output (try ls -l /proc/self/fd)
+- man: better check for duplicated MANPATH
+- mdev: add support for - ("dont stop here") char
+- mdev: if /sys/class/block exists, don't scan /sys/block
+- mdev: ignore events with "$SUBSYSTEM" == "firmware" && "$ACTION" == "remove"
+- mdev: provide $SUBSYSTEM. By Vladimir
+- modprobe/insmod for 2.4: support compressed modules. By Guenter (lists AT gknw.net)
+- modprobe: emit "can't open 'modules.dep': (errno)" instead of "module not found"
+- modprobe: rework/speedup by Timo Teras (timo.teras AT iki.fi)
+- modutils-24: fix bad interaction of xzalloc with xrealloc_vector
+- mount: support "-O option"
+- mount: stop trying to mount swap partitions
+- mount: fix CIFS support
+- mountpoint: add -n option. By Vladimir
+- nslookup: allow usage of IPv6 addresses or hostnames for DNS server name; allow for port specification. Tested to work: "nslookup google.com [::1]:5353". glibc + IPv6 address of DNS server still does not work
+- popmaildir: fix several grave bugs with using memory past end of malloc block
+- printf: fix 1.12.0 breakage (from %*d fix), it was misinterpreting "*"
+- printf: make integer format strings print long long-sized values
+- rmmod: fix bug 263 "modutils/rmmod can't remove modules with dash in name on 2.4 kernels"
+- sendmail: document and fix usage of fd #4, fix check for helper failure
+- sendmail: update by Vladimir
+- seq: add -w support. By Natanael Copa
+- seq: add support for "-s separator"
+- stat: make stat -f show filesystem "ID:" as coreutils does
+- sysctl: fix another corner case with "dots and slashes"
+- sysctl: fix broken -p [file]. Closes bug 231
+- sysctl: support recursing if name is a directory: "sysctl net.ipv4.conf". Patch by xmaks AT email.cz
+- syslogd: comment out file locking; make signal handling syncronous
+- syslogd: create logfile with 0666 (affected by umask as usual), not 0600
+- tail: fix tail +N syntax not working. Closes bug 221
+- tar: do not change new tarfile's mode, GNU tar doesn't do it
+- tar: support GNU tar's "base256" encoding
+- telnetd: correctly output 0xff char
+- telnetd: do not advertise TELNET_LFLOW, we do not support it properly
+- tftp: when we infer local name from remote (-r [/]path/path/file), strip path. This mimics wget and is generally more intuitive
+- timeout: fix parsing of -t NUM on MMU
+- top: make it work again on 2.4 kernels. Closes bug 125
+- tr: fix overflow in expand and complement, fix stop after [:class:]
+- tr: support -C as synonym to -c
+- tr: support [:xdigit:], fix handling of ranges and [x]'s
+- traceroute: rewrite. Do not emit raw IP packets, instead send UDP or ICMP packets and rely on the kernel to form IP headers, select source IP and interface
+- uname: add support for -i and -o, fix printing of unknown -p value with -a option
+- uname: support long options
+- unexpand: fix incorrect expansion
+- unzip: fix thinko with le/be conv and size. Closes bug 129
+- vi: fix several instances of major goof: when text grows, text[] might get reallocated! We were keeping around pointers to old place
+- vi: speedup and code shrink. By Walter Harms
+- volume_id: abort early on read failures. Should help with probing missing fdd's
+- volumeid: fix bug 249 "findfs finds the wrong partition"
+- wget: --post-data support. By Harald Kuthe (harald-tuxbox AT arcor.de)
+- wget: fix --header handling
+- wget: more robust EINTR detection
+8 March 2009 -- BusyBox 1.13.3 (stable) BusyBox 1.13.3. (svn, Index: libbb/Kbuild =================================================================== --- libbb/Kbuild (revision 26100) +++ libbb/Kbuild (revision 26101) @@ -122,6 +122,7 @@ lib-$(CONFIG_FEATURE_MTAB_SUPPORT) += mtab.o lib-$(CONFIG_ADDGROUP) += update_passwd.o lib-$(CONFIG_ADDUSER) += update_passwd.o +lib-$(CONFIG_DELGROUP) += update_passwd.o lib-$(CONFIG_DELUSER) += update_passwd.o lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o Index: Makefile =================================================================== --- Makefile (revision 26100) +++ Makefile (revision 26101) @@ -1,7 +1,7 @@ VERSION = 1 PATCHLEVEL = 14 SUBLEVEL = 0 -EXTRAVERSION = .svn +EXTRAVERSION = NAME = Unnamed # *DOCUMENTATION* ------------------------------------------------------------------------ r26099 | vda | 2009-04-14 16:23:33 -0500 (Tue, 14 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/util-linux/mdev.c mdev: safer handling of $SUBSYSTEM in mdev -s ------------------------------------------------------------------------ Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26098) +++ util-linux/mdev.c (revision 26099) @@ -1,6 +1,5 @@ /* vi: set sw=4 ts=4: */ /* - * * mdev - Mini udev for busybox * * Copyright 2005 Rob Landley
@@ -8,7 +7,6 @@ * * Licensed under GPL version 2, see file LICENSE in this tarball for details. */ - #include "libbb.h" #include "xregex.h" @@ -353,11 +351,13 @@ void *userData UNUSED_PARAM, int depth) { - /* Extract device subsystem -- the name of the directory under /sys/class/ */ + /* Extract device subsystem -- the name of the directory + * under /sys/class/ */ if (1 == depth) { + free(subsystem); subsystem = strrchr(fileName, '/'); if (subsystem) - subsystem++; + subsystem = xstrdup(subsystem + 1); } return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); @@ -397,17 +397,17 @@ goto out; loading: - /* tell kernel we're loading by `echo 1 > /sys/$DEVPATH/loading` */ + /* tell kernel we're loading by "echo 1 > /sys/$DEVPATH/loading" */ if (full_write(loading_fd, "1", 1) != 1) goto out; - /* load firmware by `cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data */ + /* load firmware into /sys/$DEVPATH/data */ data_fd = open("data", O_WRONLY); if (data_fd == -1) goto out; cnt = bb_copyfd_eof(firmware_fd, data_fd); - /* tell kernel result by `echo [0|-1] > /sys/$DEVPATH/loading` */ + /* tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading" */ if (cnt > 0) full_write(loading_fd, "0", 1); else ------------------------------------------------------------------------ r26097 | vda | 2009-04-14 04:58:11 -0500 (Tue, 14 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/loginutils/adduser.c pointless whitespace/comment fixes, no code changes ------------------------------------------------------------------------ Index: loginutils/adduser.c =================================================================== --- loginutils/adduser.c (revision 26096) +++ loginutils/adduser.c (revision 26097) @@ -127,8 +127,8 @@ free(p); #if ENABLE_FEATURE_SHADOWPASSWDS - p = xasprintf("!:%u:0:99999:7:::", (unsigned)(time(NULL) / 86400)); /* sp->sp_lstchg */ - /* Ignore errors: if file is missing we suppose admin doesn't want it */ + p = xasprintf("!:%u:0:99999:7:::", (unsigned)(time(NULL) / 86400)); /* sp->sp_lstchg */ + /* ignore errors: if file is missing we suppose admin doesn't want it */ update_passwd(bb_path_shadow_file, pw.pw_name, p, NULL); if (ENABLE_FEATURE_CLEAN_UP) free(p); @@ -140,7 +140,7 @@ if (!usegroup) addgroup_wrapper(&pw); - /* Clear the umask for this process so it doesn't + /* clear the umask for this process so it doesn't * screw up the permissions on the mkdir and chown. */ umask(0); if (!(option_mask32 & OPT_DONT_MAKE_HOME)) { ------------------------------------------------------------------------ r26096 | vda | 2009-04-14 03:06:59 -0500 (Tue, 14 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/libbb/update_passwd.c M /trunk/busybox/shell/hush.c M /trunk/busybox/util-linux/mdev.c randomconfig fixes ------------------------------------------------------------------------ Index: shell/hush.c =================================================================== --- shell/hush.c (revision 26095) +++ shell/hush.c (revision 26096) @@ -4069,11 +4069,15 @@ * RES_NONE case is for "for a in; do ..." (empty IN set) * and other cases to work. */ if (not_null -#if HAS_KEYWORDS +#if ENABLE_HUSH_IF || ctx->ctx_res_w == RES_FI +#endif +#if ENABLE_HUSH_LOOPS || ctx->ctx_res_w == RES_DONE || ctx->ctx_res_w == RES_FOR || ctx->ctx_res_w == RES_IN +#endif +#if ENABLE_HUSH_CASE || ctx->ctx_res_w == RES_ESAC #endif ) { Index: libbb/update_passwd.c =================================================================== --- libbb/update_passwd.c (revision 26095) +++ libbb/update_passwd.c (revision 26096) @@ -224,8 +224,10 @@ } if (changed_lines == 0) { - if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && member) +#if ENABLE_FEATURE_DEL_USER_FROM_GROUP + if (member) bb_error_msg("can't find %s in %s", member, filename); +#endif if ((ENABLE_ADDUSER || ENABLE_ADDGROUP) && applet_name[0] == 'a' && !member ) { Index: util-linux/mdev.c =================================================================== --- util-linux/mdev.c (revision 26095) +++ util-linux/mdev.c (revision 26096) @@ -98,10 +98,11 @@ if (strstr(path, "/block/")) type = S_IFBLK; -#if ENABLE_FEATURE_MDEV_CONF +#if !ENABLE_FEATURE_MDEV_CONF + mode = 0660; +#else + /* If we have config file, look up user settings */ parser = config_open2("/etc/mdev.conf", fopen_for_read); - - /* If we have config file, look up user settings */ while (1) { regmatch_t off[1 + 9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; int keep_matching; ------------------------------------------------------------------------ r26093 | vda | 2009-04-13 20:31:41 -0500 (Mon, 13 Apr 2009) | 3 lines Changed paths: M /trunk/busybox/docs/busybox.net/products.html website: update ActionTec URL to http://opensource.actiontec.com/ ------------------------------------------------------------------------ Index: docs/busybox.net/products.html =================================================================== --- docs/busybox.net/products.html (revision 26092) +++ docs/busybox.net/products.html (revision 26093) @@ -146,7 +146,7 @@ with source here ActionTec GT701-WG Wireless Gateway/DSL Modem - with source here + with source here S.M.A.R.T. Linux DLink - Model GSL-G604T, DSL-300T, and possibly other models with source here, ------------------------------------------------------------------------ r26092 | vda | 2009-04-13 19:59:37 -0500 (Mon, 13 Apr 2009) | 6 lines Changed paths: M /trunk/busybox/docs/busybox.net/subversion.html website: fix obsolete "svn co svn://busybox.net/branches/busybox_1_12_stable" example ------------------------------------------------------------------------ Index: docs/busybox.net/subversion.html =================================================================== --- docs/busybox.net/subversion.html (revision 26091) +++ docs/busybox.net/subversion.html (revision 26092) @@ -18,9 +18,9 @@ svn co svn://busybox.net/trunk/busybox
-The current stable branch can be obtained with +The stable branches can be obtained with
-svn co svn://busybox.net/branches/busybox_1_12_stable +svn co svn://busybox.net/branches/busybox_1_NN_stable
------------------------------------------------------------------------
r26091 | vda | 2009-04-13 19:51:05 -0500 (Mon, 13 Apr 2009) | 22 lines
Changed paths:
M /trunk/busybox/include/libbb.h
M /trunk/busybox/libbb/Kbuild
M /trunk/busybox/libbb/update_passwd.c
M /trunk/busybox/loginutils/addgroup.c
M /trunk/busybox/loginutils/adduser.c
M /trunk/busybox/loginutils/chpasswd.c
M /trunk/busybox/loginutils/deluser.c
M /trunk/busybox/loginutils/passwd.c
*: unify concurrent-safe update of /etc/{passwd,group,[g]shadow}
by Tito (farmatito AT tiscali.it)
function old new delta
update_passwd 743 1171 +428
bb_perror_nomsg - 9 +9
find_main 436 444 +8
passwd_main 1023 1027 +4
nameval 202 206 +4
chpasswd_main 315 319 +4
bb__parsespent 119 117 -2
adduser_main 654 650 -4
addgroup_main 345 341 -4
sv_main 1228 1222 -6
deluser_main 173 160 -13
bb_internal_putpwent 69 - -69
add_user_to_group 231 - -231
del_line_matching 460 31 -429
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 5/6 up/down: 457/-758) Total: -301 bytes
------------------------------------------------------------------------
Index: libbb/update_passwd.c
===================================================================
--- libbb/update_passwd.c (revision 26090)
+++ libbb/update_passwd.c (revision 26091)
@@ -8,9 +8,11 @@
*
* Moved from loginutils/passwd.c by Alexander Shishkin
+