Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/libbb
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 13 added
- 14 deleted
- 54 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/libbb/Config.src
r3232 r3621 17 17 config MD5_SMALL 18 18 int "MD5: Trade bytes for speed (0:fast, 3:slow)" 19 default 1 19 default 1 # all "fast or small" options default to small 20 20 range 0 3 21 21 help … … 31 31 config SHA3_SMALL 32 32 int "SHA3: Trade bytes for speed (0:fast, 1:slow)" 33 default 1 33 default 1 # all "fast or small" options default to small 34 34 range 0 1 35 35 help … … 41 41 config FEATURE_FAST_TOP 42 42 bool "Faster /proc scanning code (+100 bytes)" 43 default y43 default n # all "fast or small" options default to small 44 44 help 45 45 This option makes top (and ps) ~20% faster (or 20% less CPU hungry), … … 115 115 bool "Reverse history search" 116 116 default y 117 depends on FEATURE_EDITING _SAVEHISTORY117 depends on FEATURE_EDITING 118 118 help 119 119 Enable readline-like Ctrl-R combination for reverse history search. … … 209 209 config MONOTONIC_SYSCALL 210 210 bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" 211 default n211 default y 212 212 select PLATFORM_LINUX 213 213 help -
branches/3.3/mindi-busybox/libbb/Kbuild.src
r3232 r3621 28 28 lib-y += copyfd.o 29 29 lib-y += crc32.o 30 lib-y += create_icmp6_socket.o31 lib-y += create_icmp_socket.o32 30 lib-y += default_error_retval.o 33 31 lib-y += device_open.o 34 32 lib-y += dump.o 35 lib-y += exec able.o33 lib-y += executable.o 36 34 lib-y += fclose_nonstdin.o 37 35 lib-y += fflush_stdout_and_exit.o … … 49 47 lib-y += human_readable.o 50 48 lib-y += inet_common.o 51 lib-y += info_msg.o52 49 lib-y += inode_hash.o 53 50 lib-y += isdirectory.o … … 95 92 lib-y += str_tolower.o 96 93 lib-y += strrstr.o 94 lib-y += sysconf.o 97 95 lib-y += time.o 98 96 lib-y += trim.o … … 144 142 lib-$(CONFIG_DELUSER) += update_passwd.o 145 143 144 lib-$(CONFIG_FTPD) += correct_password.o 146 145 lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o 147 146 lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o 148 147 lib-$(CONFIG_CRYPTPW) += pw_encrypt.o 149 lib-$(CONFIG_SULOGIN) += pw_encrypt.o 148 lib-$(CONFIG_MKPASSWD) += pw_encrypt.o 149 lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o 150 150 lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o 151 151 lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o 152 152 lib-$(CONFIG_LOGIN) += pw_encrypt.o correct_password.o 153 153 lib-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) += pw_encrypt.o 154 lib-$(CONFIG_FEATURE_FTP_AUTHENTICATION) += pw_encrypt.o 154 155 155 156 lib-$(CONFIG_DF) += find_mount_point.o … … 188 189 lib-$(CONFIG_DEVFSD) += xregcomp.o 189 190 lib-$(CONFIG_FEATURE_FIND_REGEX) += xregcomp.o 191 192 # Add the experimental logging functionality, only used by zcip 193 lib-$(CONFIG_ZCIP) += logenv.o -
branches/3.3/mindi-busybox/libbb/appletlib.c
r3232 r3621 30 30 31 31 #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ 32 32 || defined(__APPLE__) \ 33 33 ) 34 34 # include <malloc.h> /* for mallopt */ … … 53 53 #include "usage_compressed.h" 54 54 55 static void run_applet_and_exit(const char *name, char **argv) NORETURN; 55 56 56 57 #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE … … 131 132 full_write2_str(" "); 132 133 full_write2_str(p); 133 full_write2_str("\n \n");134 full_write2_str("\n"); 134 135 } 135 136 if (ENABLE_FEATURE_CLEAN_UP) … … 140 141 } 141 142 142 #if NUM_APPLETS > 8143 static int applet_name_compare(const void *name, const void *idx)144 {145 int i = (int)(ptrdiff_t)idx - 1;146 return strcmp(name, APPLET_NAME(i));147 }148 #endif149 143 int FAST_FUNC find_applet_by_name(const char *name) 150 144 { 151 #if NUM_APPLETS > 8 152 /* Do a binary search to find the applet entry given the name. */145 unsigned i, max; 146 int j; 153 147 const char *p; 154 p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare); 155 /* 156 * if (!p) return -1; 157 * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :) 158 */ 159 return (int)(ptrdiff_t)p - 1; 148 149 /* The commented-out word-at-a-time code is ~40% faster, but +160 bytes. 150 * "Faster" here saves ~0.5 microsecond of real time - not worth it. 151 */ 152 #if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ 153 uint32_t n32; 154 155 /* Handle all names < 2 chars long early */ 156 if (name[0] == '\0') 157 return -1; /* "" is not a valid applet name */ 158 if (name[1] == '\0') { 159 if (!ENABLE_TEST) 160 return -1; /* 1-char name is not valid */ 161 if (name[0] != ']') 162 return -1; /* 1-char name which isn't "[" is not valid */ 163 /* applet "[" is always applet #0: */ 164 return 0; 165 } 166 #endif 167 168 p = applet_names; 169 i = 0; 170 #if KNOWN_APPNAME_OFFSETS <= 0 171 max = NUM_APPLETS; 160 172 #else 161 /* A version which does not pull in bsearch */ 162 int i = 0; 163 const char *p = applet_names; 164 while (i < NUM_APPLETS) { 165 if (strcmp(name, p) == 0) 173 max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS; 174 for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) { 175 const char *pp = applet_names + applet_nameofs[j]; 176 if (strcmp(name, pp) >= 0) { 177 //bb_error_msg("name:'%s' >= pp:'%s'", name, pp); 178 p = pp; 179 i = max - NUM_APPLETS; 180 break; 181 } 182 max -= NUM_APPLETS; 183 } 184 max /= (unsigned)KNOWN_APPNAME_OFFSETS; 185 i /= (unsigned)KNOWN_APPNAME_OFFSETS; 186 //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); 187 #endif 188 189 /* Open-coded linear search without strcmp/strlen calls for speed */ 190 191 #if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ 192 /* skip "[\0" name, it's surely not it */ 193 if (ENABLE_TEST && LONE_CHAR(p, '[')) 194 i++, p += 2; 195 /* All remaining applet names in p[] are at least 2 chars long */ 196 /* name[] is also at least 2 chars long */ 197 198 n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16); 199 while (i < max) { 200 uint32_t p32; 201 char ch; 202 203 /* Quickly check match of the first 3 bytes */ 204 move_from_unaligned32(p32, p); 205 p += 3; 206 if ((p32 & 0x00ffffff) != n32) { 207 /* Most likely case: 3 first bytes do not match */ 208 i++; 209 if ((p32 & 0x00ff0000) == '\0') 210 continue; // p[2] was NUL 211 p++; 212 if ((p32 & 0xff000000) == '\0') 213 continue; // p[3] was NUL 214 /* p[0..3] aren't matching and none is NUL, check the rest */ 215 while (*p++ != '\0') 216 continue; 217 continue; 218 } 219 220 /* Unlikely branch: first 3 bytes ([0..2]) match */ 221 if ((p32 & 0x00ff0000) == '\0') { 222 /* name is 2-byte long, it is full match */ 223 //bb_error_msg("found:'%s' i:%u", name, i); 166 224 return i; 167 p += strlen(p) + 1; 225 } 226 /* Check remaining bytes [3..NUL] */ 227 ch = (p32 >> 24); 228 j = 3; 229 while (ch == name[j]) { 230 if (ch == '\0') { 231 //bb_error_msg("found:'%s' i:%u", name, i); 232 return i; 233 } 234 ch = *++p; 235 j++; 236 } 237 /* Not a match. Skip it, including NUL */ 238 while (ch != '\0') 239 ch = *++p; 240 p++; 241 i++; 242 } 243 return -1; 244 #else 245 while (i < max) { 246 char ch; 247 j = 0; 248 /* Do we see "name\0" in applet_names[p] position? */ 249 while ((ch = *p) == name[j]) { 250 if (ch == '\0') { 251 //bb_error_msg("found:'%s' i:%u", name, i); 252 return i; /* yes */ 253 } 254 p++; 255 j++; 256 } 257 /* No. 258 * p => 1st non-matching char in applet_names[], 259 * skip to and including NUL. 260 */ 261 while (ch != '\0') 262 ch = *++p; 263 p++; 168 264 i++; 169 265 } … … 185 281 applet_name = applet; 186 282 187 /* Set locale for everybody except 'init' */ 188 if (ENABLE_LOCALE_SUPPORT && getpid() != 1) 283 if (ENABLE_LOCALE_SUPPORT) 189 284 setlocale(LC_ALL, ""); 190 285 … … 195 290 && !argv[2] 196 291 && strcmp(argv[1], "--help") == 0 197 && strncmp(applet, "busybox", 7) != 0292 && !is_prefixed_with(applet, "busybox") 198 293 ) { 199 294 /* Special case. POSIX says "test --help" … … 439 534 } 440 535 *e = ':'; /* get_uidgid needs USER:GROUP syntax */ 441 if (get_uidgid(&sct->m_ugid, s , /*allow_numeric:*/ 1) == 0) {536 if (get_uidgid(&sct->m_ugid, s) == 0) { 442 537 errmsg = "unknown user/group"; 443 538 goto pe_label; … … 459 554 goto pe_label; 460 555 } 461 462 556 } /* while (1) */ 463 557 … … 586 680 int (*lf)(const char *, const char *); 587 681 char *fpc; 682 const char *appname = applet_names; 588 683 unsigned i; 589 684 int rc; … … 596 691 fpc = concat_path_file( 597 692 custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], 598 APPLET_NAME(i));693 appname); 599 694 // debug: bb_error_msg("%slinking %s to busybox", 600 695 // use_symbolic_links ? "sym" : "", fpc); … … 604 699 } 605 700 free(fpc); 606 } 607 } 608 # else 609 # define install_links(x,y,z) ((void)0) 701 while (*appname++ != '\0') 702 continue; 703 } 704 } 705 # elif ENABLE_BUSYBOX 706 static void install_links(const char *busybox UNUSED_PARAM, 707 int use_symbolic_links UNUSED_PARAM, 708 char *custom_install_dir UNUSED_PARAM) 709 { 710 } 610 711 # endif 611 712 713 # if ENABLE_BUSYBOX 612 714 /* If we were called as "busybox..." */ 613 715 static int busybox_main(char **argv) … … 622 724 if (ENABLE_FEATURE_AUTOWIDTH) { 623 725 /* Obtain the terminal width */ 624 get_terminal_width_height(0, &output_width, NULL);726 output_width = get_terminal_width(2); 625 727 } 626 728 … … 629 731 full_write2_str(" multi-call binary.\n"); /* reuse */ 630 732 full_write2_str( 631 "BusyBox is copyrighted by many authors between 1998-201 2.\n"733 "BusyBox is copyrighted by many authors between 1998-2015.\n" 632 734 "Licensed under GPLv2. See source distribution for detailed\n" 633 735 "copyright notices.\n" … … 640 742 " or: function [arguments]...\n" 641 743 "\n" 744 IF_NOT_FEATURE_SH_STANDALONE( 642 745 "\tBusyBox is a multi-call binary that combines many common Unix\n" 643 746 "\tutilities into a single executable. Most people will create a\n" 644 747 "\tlink to busybox for each function they wish to use and BusyBox\n" 645 748 "\twill act like whatever it was invoked as.\n" 749 ) 750 IF_FEATURE_SH_STANDALONE( 751 "\tBusyBox is a multi-call binary that combines many common Unix\n" 752 "\tutilities into a single executable. The shell in this build\n" 753 "\tis configured to run built-in utilities without $PATH search.\n" 754 "\tYou don't need to install a link to busybox for each utility.\n" 755 "\tTo run external program, use full path (/sbin/ip instead of ip).\n" 756 ) 646 757 "\n" 647 758 "Currently defined functions:\n" … … 671 782 } 672 783 673 if ( strncmp(argv[1], "--list", 6) == 0) {784 if (is_prefixed_with(argv[1], "--list")) { 674 785 unsigned i = 0; 675 786 const char *a = applet_names; 676 787 dup2(1, 2); 677 788 while (*a) { 678 # if ENABLE_FEATURE_INSTALLER789 # if ENABLE_FEATURE_INSTALLER 679 790 if (argv[1][6]) /* --list-full? */ 680 791 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); 681 # endif792 # endif 682 793 full_write2_str(a); 683 794 full_write2_str("\n"); 684 795 i++; 685 a += strlen(a) + 1; 796 while (*a++ != '\0') 797 continue; 686 798 } 687 799 return 0; … … 727 839 applet_name = bb_get_last_path_component_nostrip(argv[0]); 728 840 run_applet_and_exit(applet_name, argv); 729 730 /*bb_error_msg_and_die("applet not found"); - sucks in printf */ 731 full_write2_str(applet_name); 732 full_write2_str(": applet not found\n"); 733 xfunc_die(); 734 } 841 } 842 # endif 735 843 736 844 void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) … … 743 851 /* Reinit some shared global data */ 744 852 xfunc_error_retval = EXIT_FAILURE; 745 746 applet_name = APPLET_NAME(applet_no); 747 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 748 /* Special case. POSIX says "test --help" 749 * should be no different from e.g. "test --foo". */ 750 //TODO: just compare applet_no with APPLET_NO_test 751 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) { 752 /* If you want "foo --help" to return 0: */ 753 /*xfunc_error_retval = 0;*/ 853 applet_name = bb_get_last_path_component_nostrip(argv[0]); 854 855 /* Special case. POSIX says "test --help" 856 * should be no different from e.g. "test --foo". 857 * Thus for "test", we skip --help check. 858 * "true" and "false" are also special. 859 */ 860 if (1 861 #if defined APPLET_NO_test 862 && applet_no != APPLET_NO_test 863 #endif 864 #if defined APPLET_NO_true 865 && applet_no != APPLET_NO_true 866 #endif 867 #if defined APPLET_NO_false 868 && applet_no != APPLET_NO_false 869 #endif 870 ) { 871 if (argc == 2 && strcmp(argv[1], "--help") == 0) { 872 /* Make "foo --help" exit with 0: */ 873 xfunc_error_retval = 0; 754 874 bb_show_usage(); 755 875 } … … 760 880 } 761 881 762 void FAST_FUNC run_applet_and_exit(const char *name, char **argv) 763 { 764 int applet = find_applet_by_name(name); 882 static NORETURN void run_applet_and_exit(const char *name, char **argv) 883 { 884 int applet; 885 886 # if ENABLE_BUSYBOX 887 if (is_prefixed_with(name, "busybox")) 888 exit(busybox_main(argv)); 889 # endif 890 /* find_applet_by_name() search is more expensive, so goes second */ 891 applet = find_applet_by_name(name); 765 892 if (applet >= 0) 766 893 run_applet_no_and_exit(applet, argv); 767 if (strncmp(name, "busybox", 7) == 0) 768 exit(busybox_main(argv)); 894 895 /*bb_error_msg_and_die("applet not found"); - links in printf */ 896 full_write2_str(applet_name); 897 full_write2_str(": applet not found\n"); 898 /* POSIX: "If a command is not found, the exit status shall be 127" */ 899 exit(127); 769 900 } 770 901 … … 779 910 #endif 780 911 { 912 #if 0 913 /* TODO: find a use for a block of memory between end of .bss 914 * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes" 915 * - more than 2k of wasted memory (in this particular build) 916 * *per each running process*! 917 * (If your linker does not generate "_end" name, weak attribute 918 * makes &_end == NULL, end_len == 0 here.) 919 */ 920 extern char _end[] __attribute__((weak)); 921 unsigned end_len = (-(int)_end) & 0xfff; 922 printf("_end:%p %u bytes\n", &_end, end_len); 923 #endif 924 781 925 /* Tweak malloc for reduced memory consumption */ 782 926 #ifdef M_TRIM_THRESHOLD … … 804 948 #if defined(SINGLE_APPLET_MAIN) 805 949 /* Only one applet is selected in .config */ 806 if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) {950 if (argv[1] && is_prefixed_with(argv[0], "busybox")) { 807 951 /* "busybox <applet> <params>" should still work as expected */ 808 952 argv++; … … 814 958 lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); 815 959 960 #if !ENABLE_BUSYBOX 961 if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) 962 argv++; 963 #endif 816 964 applet_name = argv[0]; 817 965 if (applet_name[0] == '-') … … 822 970 823 971 run_applet_and_exit(applet_name, argv); 824 825 /*bb_error_msg_and_die("applet not found"); - sucks in printf */ 826 full_write2_str(applet_name); 827 full_write2_str(": applet not found\n"); 828 xfunc_die(); 829 #endif 830 } 972 #endif 973 } -
branches/3.3/mindi-busybox/libbb/bb_askpass.c
r3232 r3621 2 2 /* 3 3 * Ask for a password 4 * I use a static buffer in this function. Plan accordingly.5 4 * 6 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> … … 24 23 /* Was static char[BIGNUM] */ 25 24 enum { sizeof_passwd = 128 }; 26 static char *passwd;27 25 26 char *passwd; 28 27 char *ret; 29 28 int i; … … 31 30 struct termios tio, oldtio; 32 31 32 tcflush(fd, TCIFLUSH); 33 /* Was buggy: was printing prompt *before* flushing input, 34 * which was upsetting "expect" based scripts of some users. 35 */ 33 36 fputs(prompt, stdout); 34 37 fflush_all(); 35 tcflush(fd, TCIFLUSH);36 38 37 39 tcgetattr(fd, &oldtio); … … 60 62 } 61 63 62 if (!passwd) 63 passwd = xmalloc(sizeof_passwd); 64 passwd = auto_string(xmalloc(sizeof_passwd)); 64 65 ret = passwd; 65 66 i = 0; 66 67 while (1) { 67 68 int r = read(fd, &ret[i], 1); 68 if (r < 0) { 69 if ((i == 0 && r == 0) /* EOF (^D) with no password */ 70 || r < 0 71 ) { 69 72 /* read is interrupted by timeout or ^C */ 70 73 ret = NULL; -
branches/3.3/mindi-busybox/libbb/change_identity.c
r2725 r3621 34 34 void FAST_FUNC change_identity(const struct passwd *pw) 35 35 { 36 if (initgroups(pw->pw_name, pw->pw_gid) == -1) 36 int res; 37 38 res = initgroups(pw->pw_name, pw->pw_gid); 39 endgrent(); /* helps to close a fd used internally by libc */ 40 41 if (res != 0) { 42 /* 43 * If initgroups() fails because a system call is unimplemented 44 * then we are running on a Linux kernel compiled without multiuser 45 * support (CONFIG_MULTIUSER is not defined). 46 * 47 * If we are running without multiuser support *and* the target uid 48 * already matches the current uid then we can skip the change of 49 * identity. 50 */ 51 if (errno == ENOSYS && pw->pw_uid == getuid()) { 52 return; 53 } 54 37 55 bb_perror_msg_and_die("can't set groups"); 38 endgrent(); /* helps to close a fd used internally by libc */ 56 } 57 39 58 xsetgid(pw->pw_gid); 40 59 xsetuid(pw->pw_uid); -
branches/3.3/mindi-busybox/libbb/compare_string_array.c
r2725 r3621 5 5 6 6 #include "libbb.h" 7 8 /* 9 * Return NULL if string is not prefixed with key. Return pointer to the 10 * first character in string after the prefix key. If key is an empty string, 11 * return pointer to the beginning of string. 12 */ 13 char* FAST_FUNC is_prefixed_with(const char *string, const char *key) 14 { 15 #if 0 /* Two passes over key - probably slower */ 16 int len = strlen(key); 17 if (strncmp(string, key, len) == 0) 18 return string + len; 19 return NULL; 20 #else /* Open-coded */ 21 while (*key != '\0') { 22 if (*key != *string) 23 return NULL; 24 key++; 25 string++; 26 } 27 return (char*)string; 28 #endif 29 } 30 31 /* 32 * Return NULL if string is not suffixed with key. Return pointer to the 33 * beginning of prefix key in string. If key is an empty string return pointer 34 * to the end of string. 35 */ 36 char* FAST_FUNC is_suffixed_with(const char *string, const char *key) 37 { 38 size_t key_len = strlen(key); 39 ssize_t len_diff = strlen(string) - key_len; 40 41 if (len_diff >= 0) { 42 string += len_diff; 43 if (strcmp(string, key) == 0) { 44 return (char*)string; 45 } 46 } 47 48 return NULL; 49 } 7 50 8 51 /* returns the array index of the string */ … … 40 83 { 41 84 int i; 42 int len = strlen(key); 43 if (len) { 85 if (key[0]) { 44 86 for (i = 0; string_array[i] != 0; i++) { 45 if ( strncmp(string_array[i], key, len) == 0) {87 if (is_prefixed_with(string_array[i], key)) { 46 88 return i; 47 89 } … … 94 136 } 95 137 #endif 138 139 #if ENABLE_UNIT_TEST 140 141 BBUNIT_DEFINE_TEST(is_prefixed_with) 142 { 143 BBUNIT_ASSERT_STREQ(" bar", is_prefixed_with("foo bar", "foo")); 144 BBUNIT_ASSERT_STREQ("bar", is_prefixed_with("foo bar", "foo ")); 145 BBUNIT_ASSERT_STREQ("", is_prefixed_with("foo", "foo")); 146 BBUNIT_ASSERT_STREQ("foo", is_prefixed_with("foo", "")); 147 BBUNIT_ASSERT_STREQ("", is_prefixed_with("", "")); 148 149 BBUNIT_ASSERT_NULL(is_prefixed_with("foo", "bar foo")); 150 BBUNIT_ASSERT_NULL(is_prefixed_with("foo foo", "bar")); 151 BBUNIT_ASSERT_NULL(is_prefixed_with("", "foo")); 152 153 BBUNIT_ENDTEST; 154 } 155 156 BBUNIT_DEFINE_TEST(is_suffixed_with) 157 { 158 BBUNIT_ASSERT_STREQ("bar", is_suffixed_with("foo bar", "bar")); 159 BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo")); 160 BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", "")); 161 BBUNIT_ASSERT_STREQ("", is_suffixed_with("", "")); 162 BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("barfoofoo", "foo")); 163 164 BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo")); 165 BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar")); 166 BBUNIT_ASSERT_NULL(is_suffixed_with("", "foo")); 167 168 BBUNIT_ENDTEST; 169 } 170 171 #endif /* ENABLE_UNIT_TEST */ -
branches/3.3/mindi-busybox/libbb/copy_file.c
r3232 r3621 65 65 return -1; /* error */ 66 66 } 67 #if ENABLE_FEATURE_CP_LONG_OPTIONS 68 if (flags & FILEUTILS_RMDEST) 69 if (flags & FILEUTILS_VERBOSE) 70 printf("removed '%s'\n", dest); 71 #endif 67 72 return 1; /* ok (to try again) */ 68 73 } … … 211 216 } 212 217 218 if (dest_exists) { 219 if (flags & FILEUTILS_UPDATE) { 220 if (source_stat.st_mtime <= dest_stat.st_mtime) { 221 return 0; /* source file must be newer */ 222 } 223 } 224 #if ENABLE_FEATURE_CP_LONG_OPTIONS 225 if (flags & FILEUTILS_RMDEST) { 226 ovr = ask_and_unlink(dest, flags); 227 if (ovr <= 0) 228 return ovr; 229 dest_exists = 0; 230 } 231 #endif 232 } 233 213 234 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { 214 235 int (*lf)(const char *oldpath, const char *newpath); … … 390 411 } 391 412 413 if (flags & FILEUTILS_VERBOSE) { 414 printf("'%s' -> '%s'\n", source, dest); 415 } 416 392 417 return retval; 393 418 } -
branches/3.3/mindi-busybox/libbb/copyfd.c
r2725 r3621 9 9 10 10 #include "libbb.h" 11 #if ENABLE_FEATURE_USE_SENDFILE 12 # include <sys/sendfile.h> 13 #else 14 # define sendfile(a,b,c,d) (-1) 15 #endif 16 17 /* 18 * We were using 0x7fff0000 as sendfile chunk size, but it 19 * was seen to cause largish delays when user tries to ^C a file copy. 20 * Let's use a saner size. 21 * Note: needs to be >= max(CONFIG_FEATURE_COPYBUF_KB), 22 * or else "copy to eof" code will use neddlesly short reads. 23 */ 24 #define SENDFILE_BIGBUF (16*1024*1024) 11 25 12 26 /* Used by NOFORK applets (e.g. cat) - must not use xmalloc. … … 19 33 off_t total = 0; 20 34 bool continue_on_write_error = 0; 21 #if CONFIG_FEATURE_COPYBUF_KB <= 4 35 ssize_t sendfile_sz; 36 #if CONFIG_FEATURE_COPYBUF_KB > 4 37 char *buffer = buffer; /* for compiler */ 38 int buffer_size = 0; 39 #else 22 40 char buffer[CONFIG_FEATURE_COPYBUF_KB * 1024]; 23 41 enum { buffer_size = sizeof(buffer) }; 24 #else25 char *buffer;26 int buffer_size;27 42 #endif 28 43 … … 32 47 } 33 48 34 #if CONFIG_FEATURE_COPYBUF_KB > 435 if (size > 0 && size <= 4 * 1024)36 goto use_small_buf;37 /* We want page-aligned buffer, just in case kernel is clever38 * and can do page-aligned io more efficiently */39 buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024,40 PROT_READ | PROT_WRITE,41 MAP_PRIVATE | MAP_ANON,42 /* ignored: */ -1, 0);43 buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024;44 if (buffer == MAP_FAILED) {45 use_small_buf:46 buffer = alloca(4 * 1024);47 buffer_size = 4 * 1024;48 }49 #endif50 51 49 if (src_fd < 0) 52 50 goto out; 53 51 52 sendfile_sz = !ENABLE_FEATURE_USE_SENDFILE 53 ? 0 54 : SENDFILE_BIGBUF; 54 55 if (!size) { 55 size = buffer_size;56 size = SENDFILE_BIGBUF; 56 57 status = 1; /* copy until eof */ 57 58 } … … 60 61 ssize_t rd; 61 62 62 rd = safe_read(src_fd, buffer, size > buffer_size ? buffer_size : size); 63 63 if (sendfile_sz) { 64 rd = sendfile(dst_fd, src_fd, NULL, 65 size > sendfile_sz ? sendfile_sz : size); 66 if (rd >= 0) 67 goto read_ok; 68 sendfile_sz = 0; /* do not try sendfile anymore */ 69 } 70 #if CONFIG_FEATURE_COPYBUF_KB > 4 71 if (buffer_size == 0) { 72 if (size > 0 && size <= 4 * 1024) 73 goto use_small_buf; 74 /* We want page-aligned buffer, just in case kernel is clever 75 * and can do page-aligned io more efficiently */ 76 buffer = mmap(NULL, CONFIG_FEATURE_COPYBUF_KB * 1024, 77 PROT_READ | PROT_WRITE, 78 MAP_PRIVATE | MAP_ANON, 79 /* ignored: */ -1, 0); 80 buffer_size = CONFIG_FEATURE_COPYBUF_KB * 1024; 81 if (buffer == MAP_FAILED) { 82 use_small_buf: 83 buffer = alloca(4 * 1024); 84 buffer_size = 4 * 1024; 85 } 86 } 87 #endif 88 rd = safe_read(src_fd, buffer, 89 size > buffer_size ? buffer_size : size); 90 if (rd < 0) { 91 bb_perror_msg(bb_msg_read_error); 92 break; 93 } 94 read_ok: 64 95 if (!rd) { /* eof - all done */ 65 96 status = 0; 66 97 break; 67 98 } 68 if (rd < 0) {69 bb_perror_msg(bb_msg_read_error);70 break;71 }72 99 /* dst_fd == -1 is a fake, else... */ 73 if (dst_fd >= 0 ) {100 if (dst_fd >= 0 && !sendfile_sz) { 74 101 ssize_t wr = full_write(dst_fd, buffer, rd); 75 102 if (wr < rd) { … … 93 120 out: 94 121 95 #if CONFIG_FEATURE_COPYBUF_KB > 4 96 if (buffer_size != 4 * 1024) 122 if (buffer_size > 4 * 1024) 97 123 munmap(buffer, buffer_size); 98 #endif99 124 return status ? -1 : total; 100 125 } -
branches/3.3/mindi-busybox/libbb/correct_password.c
r3232 r3621 31 31 #include "libbb.h" 32 32 33 /* Ask the user for a password. 34 * Return 1 if the user gives the correct password for entry PW, 35 * 0 if not. Return 1 without asking if PW has an empty password. 36 * 37 * NULL pw means "just fake it for login with bad username" */ 33 #define SHADOW_BUFSIZE 256 38 34 39 int FAST_FUNC correct_password(const struct passwd *pw) 35 /* Retrieve encrypted password string for pw. 36 * If pw == NULL, return a string which fails password check against any 37 * password. 38 */ 39 #if !ENABLE_FEATURE_SHADOWPASSWDS 40 #define get_passwd(pw, buffer) get_passwd(pw) 41 #endif 42 static const char *get_passwd(const struct passwd *pw, char buffer[SHADOW_BUFSIZE]) 40 43 { 41 char *unencrypted, *encrypted; 42 const char *correct; 43 int r; 44 /* fake salt. crypt() can choke otherwise. */ 45 correct = "aa"; 46 if (!pw) { 47 /* "aa" will never match */ 48 goto fake_it; 49 } 50 correct = pw->pw_passwd; 44 const char *pass; 45 46 if (!pw) 47 return "aa"; /* "aa" will never match */ 48 49 pass = pw->pw_passwd; 51 50 #if ENABLE_FEATURE_SHADOWPASSWDS 52 51 /* Using _r function to avoid pulling in static buffers */ 53 if (( correct[0] == 'x' || correct[0] == '*') && !correct[1]) {52 if ((pass[0] == 'x' || pass[0] == '*') && !pass[1]) { 54 53 struct spwd spw; 55 char buffer[256];54 int r; 56 55 /* getspnam_r may return 0 yet set result to NULL. 57 56 * At least glibc 2.4 does this. Be extra paranoid here. */ 58 57 struct spwd *result = NULL; 59 r = getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result);60 correct= (r || !result) ? "aa" : result->sp_pwdp;58 r = getspnam_r(pw->pw_name, &spw, buffer, SHADOW_BUFSIZE, &result); 59 pass = (r || !result) ? "aa" : result->sp_pwdp; 61 60 } 62 61 #endif 62 return pass; 63 } 63 64 64 if (!correct[0]) /* empty password field? */ 65 /* 66 * Return 1 if PW has an empty password. 67 * Return 1 if the user gives the correct password for entry PW, 68 * 0 if not. 69 * NULL pw means "just fake it for login with bad username" 70 */ 71 int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) 72 { 73 IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];) 74 char *encrypted; 75 const char *pw_pass; 76 int r; 77 78 pw_pass = get_passwd(pw, buffer); 79 if (!pw_pass[0]) { /* empty password field? */ 80 return 1; 81 } 82 83 encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1); 84 r = (strcmp(encrypted, pw_pass) == 0); 85 free(encrypted); 86 return r; 87 } 88 89 90 /* Ask the user for a password. 91 * Return 1 without asking if PW has an empty password. 92 * Return -1 on EOF, error while reading input, or timeout. 93 * Return 1 if the user gives the correct password for entry PW, 94 * 0 if not. 95 * 96 * NULL pw means "just fake it for login with bad username" 97 */ 98 int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, 99 int timeout, const char *prompt) 100 { 101 IF_FEATURE_SHADOWPASSWDS(char buffer[SHADOW_BUFSIZE];) 102 char *plaintext; 103 const char *pw_pass; 104 int r; 105 106 pw_pass = get_passwd(pw, buffer); 107 if (!pw_pass[0]) /* empty password field? */ 65 108 return 1; 66 109 67 fake_it: 68 unencrypted = bb_ask_stdin("Password: ");69 if (!unencrypted) {70 return 0;110 plaintext = bb_ask(STDIN_FILENO, timeout, prompt); 111 if (!plaintext) { 112 /* EOF (such as ^D) or error (such as ^C) or timeout */ 113 return -1; 71 114 } 72 encrypted = pw_encrypt(unencrypted, correct, 1); 73 r = (strcmp(encrypted, correct) == 0); 74 free(encrypted); 75 memset(unencrypted, 0, strlen(unencrypted)); 115 116 r = check_password(pw, plaintext); 117 nuke_str(plaintext); 76 118 return r; 77 119 } 120 121 int FAST_FUNC ask_and_check_password(const struct passwd *pw) 122 { 123 return ask_and_check_password_extended(pw, 0, "Password: "); 124 } -
branches/3.3/mindi-busybox/libbb/dump.c
r3232 r3621 334 334 } 335 335 } 336 if (fseek (stdin, dumper->pub.dump_skip, SEEK_SET)) {336 if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) { 337 337 bb_simple_perror_msg_and_die(fname); 338 338 } -
branches/3.3/mindi-busybox/libbb/fclose_nonstdin.c
r2725 r3621 19 19 /* Some more paranoid applets want ferror() check too */ 20 20 int r = ferror(f); /* NB: does NOT set errno! */ 21 if (r) errno = EIO; /* so we'll help it */ 21 if (r) 22 errno = EIO; /* so we'll help it */ 22 23 if (f != stdin) 23 24 return (r | fclose(f)); /* fclose does set errno on error */ -
branches/3.3/mindi-busybox/libbb/fflush_stdout_and_exit.c
r2725 r3621 16 16 void FAST_FUNC fflush_stdout_and_exit(int retval) 17 17 { 18 xfunc_error_retval = retval; 18 19 if (fflush(stdout)) 19 20 bb_perror_msg_and_die(bb_msg_standard_output); 20 21 if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { 22 /* We are in NOFORK applet. Do not exit() directly, 23 * but use xfunc_die() */ 24 xfunc_error_retval = retval; 25 xfunc_die(); 26 } 27 28 exit(retval); 21 /* In case we are in NOFORK applet. Do not exit() directly, 22 * but use xfunc_die() */ 23 xfunc_die(); 29 24 } -
branches/3.3/mindi-busybox/libbb/getpty.c
r3232 r3621 17 17 #if ENABLE_FEATURE_DEVPTS 18 18 p = open("/dev/ptmx", O_RDWR); 19 if (p > 0) {19 if (p >= 0) { 20 20 grantpt(p); /* chmod+chown corresponding slave pty */ 21 21 unlockpt(p); /* (what does this do?) */ -
branches/3.3/mindi-busybox/libbb/hash_md5_sha.c
r3232 r3621 85 85 t = bb_bswap_64(t); 86 86 /* wbuffer is suitably aligned for this */ 87 *( uint64_t *) (&ctx->wbuffer[64 - 8]) = t;87 *(bb__aliased_uint64_t *) (&ctx->wbuffer[64 - 8]) = t; 88 88 } 89 89 ctx->process_block(ctx); … … 138 138 /* Before we start, one word to the strange constants. 139 139 They are defined in RFC 1321 as 140 T[i] = (int)( 4294967296.0* fabs(sin(i))), i=1..64140 T[i] = (int)(2^32 * fabs(sin(i))), i=1..64 141 141 */ 142 142 static const uint32_t C_array[] = { … … 214 214 temp += FH(B, C, D); 215 215 break; 216 case 3:216 default: /* case 3 */ 217 217 temp += FI(B, C, D); 218 218 } … … 278 278 #else /* MD5_SMALL == 0 or 1 */ 279 279 280 uint32_t A_save = A;281 uint32_t B_save = B;282 uint32_t C_save = C;283 uint32_t D_save = D;284 280 # if MD5_SMALL == 1 285 281 const uint32_t *pc; … … 426 422 # endif 427 423 /* Add checksum to the starting values */ 428 ctx->hash[0] = A_save +A;429 ctx->hash[1] = B_save +B;430 ctx->hash[2] = C_save +C;431 ctx->hash[3] = D_save +D;424 ctx->hash[0] += A; 425 ctx->hash[1] += B; 426 ctx->hash[2] += C; 427 ctx->hash[3] += D; 432 428 #endif 433 429 } … … 884 880 t = ctx->total64[0] << 3; 885 881 t = SWAP_BE64(t); 886 *( uint64_t *) (&ctx->wbuffer[128 - 8]) = t;882 *(bb__aliased_uint64_t *) (&ctx->wbuffer[128 - 8]) = t; 887 883 t = (ctx->total64[1] << 3) | (ctx->total64[0] >> 61); 888 884 t = SWAP_BE64(t); 889 *( uint64_t *) (&ctx->wbuffer[128 - 16]) = t;885 *(bb__aliased_uint64_t *) (&ctx->wbuffer[128 - 16]) = t; 890 886 } 891 887 sha512_process_block128(ctx); … … 927 923 #endif 928 924 925 #define OPTIMIZE_SHA3_FOR_32 0 926 /* 927 * SHA3 can be optimized for 32-bit CPUs with bit-slicing: 928 * every 64-bit word of state[] can be split into two 32-bit words 929 * by even/odd bits. In this form, all rotations of sha3 round 930 * are 32-bit - and there are lots of them. 931 * However, it requires either splitting/combining state words 932 * before/after sha3 round (code does this now) 933 * or shuffling bits before xor'ing them into state and in sha3_end. 934 * Without shuffling, bit-slicing results in -130 bytes of code 935 * and marginal speedup (but of course it gives wrong result). 936 * With shuffling it works, but +260 code bytes, and slower. 937 * Disabled for now: 938 */ 939 #if 0 /* LONG_MAX == 0x7fffffff */ 940 # undef OPTIMIZE_SHA3_FOR_32 941 # define OPTIMIZE_SHA3_FOR_32 1 942 #endif 943 929 944 enum { 930 945 SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */ 931 946 }; 947 948 #if OPTIMIZE_SHA3_FOR_32 949 /* This splits every 64-bit word into a pair of 32-bit words, 950 * even bits go into first word, odd bits go to second one. 951 * The conversion is done in-place. 952 */ 953 static void split_halves(uint64_t *state) 954 { 955 /* Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ 956 uint32_t *s32 = (uint32_t*)state; 957 uint32_t t, x0, x1; 958 int i; 959 for (i = 24; i >= 0; --i) { 960 x0 = s32[0]; 961 t = (x0 ^ (x0 >> 1)) & 0x22222222; x0 = x0 ^ t ^ (t << 1); 962 t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0C; x0 = x0 ^ t ^ (t << 2); 963 t = (x0 ^ (x0 >> 4)) & 0x00F000F0; x0 = x0 ^ t ^ (t << 4); 964 t = (x0 ^ (x0 >> 8)) & 0x0000FF00; x0 = x0 ^ t ^ (t << 8); 965 x1 = s32[1]; 966 t = (x1 ^ (x1 >> 1)) & 0x22222222; x1 = x1 ^ t ^ (t << 1); 967 t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0C; x1 = x1 ^ t ^ (t << 2); 968 t = (x1 ^ (x1 >> 4)) & 0x00F000F0; x1 = x1 ^ t ^ (t << 4); 969 t = (x1 ^ (x1 >> 8)) & 0x0000FF00; x1 = x1 ^ t ^ (t << 8); 970 *s32++ = (x0 & 0x0000FFFF) | (x1 << 16); 971 *s32++ = (x0 >> 16) | (x1 & 0xFFFF0000); 972 } 973 } 974 /* The reverse operation */ 975 static void combine_halves(uint64_t *state) 976 { 977 uint32_t *s32 = (uint32_t*)state; 978 uint32_t t, x0, x1; 979 int i; 980 for (i = 24; i >= 0; --i) { 981 x0 = s32[0]; 982 x1 = s32[1]; 983 t = (x0 & 0x0000FFFF) | (x1 << 16); 984 x1 = (x0 >> 16) | (x1 & 0xFFFF0000); 985 x0 = t; 986 t = (x0 ^ (x0 >> 8)) & 0x0000FF00; x0 = x0 ^ t ^ (t << 8); 987 t = (x0 ^ (x0 >> 4)) & 0x00F000F0; x0 = x0 ^ t ^ (t << 4); 988 t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0C; x0 = x0 ^ t ^ (t << 2); 989 t = (x0 ^ (x0 >> 1)) & 0x22222222; x0 = x0 ^ t ^ (t << 1); 990 *s32++ = x0; 991 t = (x1 ^ (x1 >> 8)) & 0x0000FF00; x1 = x1 ^ t ^ (t << 8); 992 t = (x1 ^ (x1 >> 4)) & 0x00F000F0; x1 = x1 ^ t ^ (t << 4); 993 t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0C; x1 = x1 ^ t ^ (t << 2); 994 t = (x1 ^ (x1 >> 1)) & 0x22222222; x1 = x1 ^ t ^ (t << 1); 995 *s32++ = x1; 996 } 997 } 998 #endif 932 999 933 1000 /* … … 938 1005 enum { NROUNDS = 24 }; 939 1006 940 /* Elements should be 64-bit, but top half is always zero or 0x80000000. 941 * We encode 63rd bits in a separate word below. 942 * Same is true for 31th bits, which lets us use 16-bit table instead of 64-bit. 943 * The speed penalty is lost in the noise. 944 */ 1007 #if OPTIMIZE_SHA3_FOR_32 1008 /* 1009 static const uint32_t IOTA_CONST_0[NROUNDS] = { 1010 0x00000001UL, 1011 0x00000000UL, 1012 0x00000000UL, 1013 0x00000000UL, 1014 0x00000001UL, 1015 0x00000001UL, 1016 0x00000001UL, 1017 0x00000001UL, 1018 0x00000000UL, 1019 0x00000000UL, 1020 0x00000001UL, 1021 0x00000000UL, 1022 0x00000001UL, 1023 0x00000001UL, 1024 0x00000001UL, 1025 0x00000001UL, 1026 0x00000000UL, 1027 0x00000000UL, 1028 0x00000000UL, 1029 0x00000000UL, 1030 0x00000001UL, 1031 0x00000000UL, 1032 0x00000001UL, 1033 0x00000000UL, 1034 }; 1035 ** bits are in lsb: 0101 0000 1111 0100 1111 0001 1036 */ 1037 uint32_t IOTA_CONST_0bits = (uint32_t)(0x0050f4f1); 1038 static const uint32_t IOTA_CONST_1[NROUNDS] = { 1039 0x00000000UL, 1040 0x00000089UL, 1041 0x8000008bUL, 1042 0x80008080UL, 1043 0x0000008bUL, 1044 0x00008000UL, 1045 0x80008088UL, 1046 0x80000082UL, 1047 0x0000000bUL, 1048 0x0000000aUL, 1049 0x00008082UL, 1050 0x00008003UL, 1051 0x0000808bUL, 1052 0x8000000bUL, 1053 0x8000008aUL, 1054 0x80000081UL, 1055 0x80000081UL, 1056 0x80000008UL, 1057 0x00000083UL, 1058 0x80008003UL, 1059 0x80008088UL, 1060 0x80000088UL, 1061 0x00008000UL, 1062 0x80008082UL, 1063 }; 1064 1065 uint32_t *const s32 = (uint32_t*)state; 1066 unsigned round; 1067 1068 split_halves(state); 1069 1070 for (round = 0; round < NROUNDS; round++) { 1071 unsigned x; 1072 1073 /* Theta */ 1074 { 1075 uint32_t BC[20]; 1076 for (x = 0; x < 10; ++x) { 1077 BC[x+10] = BC[x] = s32[x]^s32[x+10]^s32[x+20]^s32[x+30]^s32[x+40]; 1078 } 1079 for (x = 0; x < 10; x += 2) { 1080 uint32_t ta, tb; 1081 ta = BC[x+8] ^ rotl32(BC[x+3], 1); 1082 tb = BC[x+9] ^ BC[x+2]; 1083 s32[x+0] ^= ta; 1084 s32[x+1] ^= tb; 1085 s32[x+10] ^= ta; 1086 s32[x+11] ^= tb; 1087 s32[x+20] ^= ta; 1088 s32[x+21] ^= tb; 1089 s32[x+30] ^= ta; 1090 s32[x+31] ^= tb; 1091 s32[x+40] ^= ta; 1092 s32[x+41] ^= tb; 1093 } 1094 } 1095 /* RhoPi */ 1096 { 1097 uint32_t t0a,t0b, t1a,t1b; 1098 t1a = s32[1*2+0]; 1099 t1b = s32[1*2+1]; 1100 1101 #define RhoPi(PI_LANE, ROT_CONST) \ 1102 t0a = s32[PI_LANE*2+0];\ 1103 t0b = s32[PI_LANE*2+1];\ 1104 if (ROT_CONST & 1) {\ 1105 s32[PI_LANE*2+0] = rotl32(t1b, ROT_CONST/2+1);\ 1106 s32[PI_LANE*2+1] = ROT_CONST == 1 ? t1a : rotl32(t1a, ROT_CONST/2+0);\ 1107 } else {\ 1108 s32[PI_LANE*2+0] = rotl32(t1a, ROT_CONST/2);\ 1109 s32[PI_LANE*2+1] = rotl32(t1b, ROT_CONST/2);\ 1110 }\ 1111 t1a = t0a; t1b = t0b; 1112 1113 RhoPi(10, 1) 1114 RhoPi( 7, 3) 1115 RhoPi(11, 6) 1116 RhoPi(17,10) 1117 RhoPi(18,15) 1118 RhoPi( 3,21) 1119 RhoPi( 5,28) 1120 RhoPi(16,36) 1121 RhoPi( 8,45) 1122 RhoPi(21,55) 1123 RhoPi(24, 2) 1124 RhoPi( 4,14) 1125 RhoPi(15,27) 1126 RhoPi(23,41) 1127 RhoPi(19,56) 1128 RhoPi(13, 8) 1129 RhoPi(12,25) 1130 RhoPi( 2,43) 1131 RhoPi(20,62) 1132 RhoPi(14,18) 1133 RhoPi(22,39) 1134 RhoPi( 9,61) 1135 RhoPi( 6,20) 1136 RhoPi( 1,44) 1137 #undef RhoPi 1138 } 1139 /* Chi */ 1140 for (x = 0; x <= 40;) { 1141 uint32_t BC0, BC1, BC2, BC3, BC4; 1142 BC0 = s32[x + 0*2]; 1143 BC1 = s32[x + 1*2]; 1144 BC2 = s32[x + 2*2]; 1145 s32[x + 0*2] = BC0 ^ ((~BC1) & BC2); 1146 BC3 = s32[x + 3*2]; 1147 s32[x + 1*2] = BC1 ^ ((~BC2) & BC3); 1148 BC4 = s32[x + 4*2]; 1149 s32[x + 2*2] = BC2 ^ ((~BC3) & BC4); 1150 s32[x + 3*2] = BC3 ^ ((~BC4) & BC0); 1151 s32[x + 4*2] = BC4 ^ ((~BC0) & BC1); 1152 x++; 1153 BC0 = s32[x + 0*2]; 1154 BC1 = s32[x + 1*2]; 1155 BC2 = s32[x + 2*2]; 1156 s32[x + 0*2] = BC0 ^ ((~BC1) & BC2); 1157 BC3 = s32[x + 3*2]; 1158 s32[x + 1*2] = BC1 ^ ((~BC2) & BC3); 1159 BC4 = s32[x + 4*2]; 1160 s32[x + 2*2] = BC2 ^ ((~BC3) & BC4); 1161 s32[x + 3*2] = BC3 ^ ((~BC4) & BC0); 1162 s32[x + 4*2] = BC4 ^ ((~BC0) & BC1); 1163 x += 9; 1164 } 1165 /* Iota */ 1166 s32[0] ^= IOTA_CONST_0bits & 1; 1167 IOTA_CONST_0bits >>= 1; 1168 s32[1] ^= IOTA_CONST_1[round]; 1169 } 1170 1171 combine_halves(state); 1172 #else 1173 /* Native 64-bit algorithm */ 945 1174 static const uint16_t IOTA_CONST[NROUNDS] = { 1175 /* Elements should be 64-bit, but top half is always zero 1176 * or 0x80000000. We encode 63rd bits in a separate word below. 1177 * Same is true for 31th bits, which lets us use 16-bit table 1178 * instead of 64-bit. The speed penalty is lost in the noise. 1179 */ 946 1180 0x0001, 947 1181 0x8082, … … 984 1218 /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/ 985 1219 986 unsigned x , y;1220 unsigned x; 987 1221 unsigned round; 988 1222 … … 1046 1280 #undef RhoPi_twice 1047 1281 } 1048 1049 1282 /* Chi */ 1050 for (y = 0; y <= 20; y += 5) { 1283 # if LONG_MAX > 0x7fffffff 1284 for (x = 0; x <= 20; x += 5) { 1051 1285 uint64_t BC0, BC1, BC2, BC3, BC4; 1052 BC0 = state[ y+ 0];1053 BC1 = state[ y+ 1];1054 BC2 = state[ y+ 2];1055 state[ y+ 0] = BC0 ^ ((~BC1) & BC2);1056 BC3 = state[ y+ 3];1057 state[ y+ 1] = BC1 ^ ((~BC2) & BC3);1058 BC4 = state[ y+ 4];1059 state[ y+ 2] = BC2 ^ ((~BC3) & BC4);1060 state[ y+ 3] = BC3 ^ ((~BC4) & BC0);1061 state[ y+ 4] = BC4 ^ ((~BC0) & BC1);1286 BC0 = state[x + 0]; 1287 BC1 = state[x + 1]; 1288 BC2 = state[x + 2]; 1289 state[x + 0] = BC0 ^ ((~BC1) & BC2); 1290 BC3 = state[x + 3]; 1291 state[x + 1] = BC1 ^ ((~BC2) & BC3); 1292 BC4 = state[x + 4]; 1293 state[x + 2] = BC2 ^ ((~BC3) & BC4); 1294 state[x + 3] = BC3 ^ ((~BC4) & BC0); 1295 state[x + 4] = BC4 ^ ((~BC0) & BC1); 1062 1296 } 1063 1297 # else 1298 /* Reduced register pressure version 1299 * for register-starved 32-bit arches 1300 * (i386: -95 bytes, and it is _faster_) 1301 */ 1302 for (x = 0; x <= 40;) { 1303 uint32_t BC0, BC1, BC2, BC3, BC4; 1304 uint32_t *const s32 = (uint32_t*)state; 1305 # if SHA3_SMALL 1306 do_half: 1307 # endif 1308 BC0 = s32[x + 0*2]; 1309 BC1 = s32[x + 1*2]; 1310 BC2 = s32[x + 2*2]; 1311 s32[x + 0*2] = BC0 ^ ((~BC1) & BC2); 1312 BC3 = s32[x + 3*2]; 1313 s32[x + 1*2] = BC1 ^ ((~BC2) & BC3); 1314 BC4 = s32[x + 4*2]; 1315 s32[x + 2*2] = BC2 ^ ((~BC3) & BC4); 1316 s32[x + 3*2] = BC3 ^ ((~BC4) & BC0); 1317 s32[x + 4*2] = BC4 ^ ((~BC0) & BC1); 1318 x++; 1319 # if SHA3_SMALL 1320 if (x & 1) 1321 goto do_half; 1322 x += 8; 1323 # else 1324 BC0 = s32[x + 0*2]; 1325 BC1 = s32[x + 1*2]; 1326 BC2 = s32[x + 2*2]; 1327 s32[x + 0*2] = BC0 ^ ((~BC1) & BC2); 1328 BC3 = s32[x + 3*2]; 1329 s32[x + 1*2] = BC1 ^ ((~BC2) & BC3); 1330 BC4 = s32[x + 4*2]; 1331 s32[x + 2*2] = BC2 ^ ((~BC3) & BC4); 1332 s32[x + 3*2] = BC3 ^ ((~BC4) & BC0); 1333 s32[x + 4*2] = BC4 ^ ((~BC0) & BC1); 1334 x += 9; 1335 # endif 1336 } 1337 # endif /* long is 32-bit */ 1064 1338 /* Iota */ 1065 1339 state[0] ^= IOTA_CONST[round] … … 1073 1347 } 1074 1348 } 1349 #endif 1075 1350 } 1076 1351 -
branches/3.3/mindi-busybox/libbb/human_readable.c
r2725 r3621 15 15 * The base ten "bytes" output could be handled similarly. 16 16 * 17 * 2) This routine alwaysoutputs a decimal point and a tenths digit when18 * display_unit != 0. Hence, it isn't uncommon for the returned string17 * 2) This routine outputs a decimal point and a tenths digit when 18 * display_unit == 0. Hence, it isn't uncommon for the returned string 19 19 * to have a length of 5 or 6. 20 20 * 21 * It might be nice to add a flag to indicate no decimal digits in 22 * that case. This could be either an additional parameter, or a 23 * special value of display_unit. Such a flag would also be nice for du. 24 * 25 * Some code to omit the decimal point and tenths digit is sketched out 26 * and "#if 0"'d below. 21 * If block_size is also 0, no decimal digits are printed. 27 22 * 28 23 * Licensed under GPLv2, see file LICENSE in this source tree. … … 37 32 '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' 38 33 }; 39 40 static char *str;41 34 42 35 unsigned frac; /* 0..9 - the fractional digit */ … … 82 75 } 83 76 84 if (!str) { 85 /* sufficient for any width of val */ 86 str = xmalloc(sizeof(val)*3 + 2 + 3); 87 } 88 sprintf(str, fmt, val, frac, *u); 89 return str; 77 return auto_string(xasprintf(fmt, val, frac, *u)); 90 78 } 91 79 … … 95 83 /* Convert unsigned long long value into compact 5-char representation. 96 84 * String is not terminated (buf[5] is untouched) */ 97 voidFAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale)85 char* FAST_FUNC smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) 98 86 { 99 87 const char *fmt; … … 146 134 buf[4] = scale[idx]; /* typically scale = " kmgt..." */ 147 135 } 136 return buf + 5; 148 137 } 149 138 … … 151 140 * representation. Examples: "1234", "1.2k", " 27M", "123T" 152 141 * String is not terminated (buf[4] is untouched) */ 153 voidFAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale)142 char* FAST_FUNC smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) 154 143 { 155 144 const char *fmt; … … 195 184 buf[3] = scale[idx]; /* typically scale = " kmgt..." */ 196 185 } 186 return buf + 4; 197 187 } -
branches/3.3/mindi-busybox/libbb/inet_common.c
r3232 r3621 33 33 } 34 34 /* If we expect this to be a hostname, try hostname database first */ 35 #ifdef DEBUG36 35 if (hostfirst) { 36 #ifdef DEBUG 37 37 bb_error_msg("gethostbyname(%s)", name); 38 } 39 #endif 40 if (hostfirst) { 38 #endif 41 39 hp = gethostbyname(name); 42 if (hp != NULL) {40 if (hp) { 43 41 memcpy(&s_in->sin_addr, hp->h_addr_list[0], 44 42 sizeof(struct in_addr)); … … 52 50 #endif 53 51 np = getnetbyname(name); 54 if (np != NULL) {52 if (np) { 55 53 s_in->sin_addr.s_addr = htonl(np->n_net); 56 54 return 1; … … 67 65 #endif 68 66 hp = gethostbyname(name); 69 if ( hp == NULL) {67 if (!hp) { 70 68 return -1; 71 69 } … … 75 73 76 74 77 /* numeric: & 0x8000: default instead of *,75 /* numeric: & 0x8000: "default" instead of "*", 78 76 * & 0x4000: host instead of net, 79 77 * & 0x0fff: don't resolve … … 84 82 struct addr { 85 83 struct addr *next; 86 struct sockaddr_in addr;87 inthost;84 uint32_t nip; 85 smallint is_host; 88 86 char name[1]; 89 87 }; … … 92 90 struct addr *pn; 93 91 char *name; 94 uint32_t ad, host_ad;95 int host = 0;92 uint32_t nip; 93 smallint is_host; 96 94 97 95 if (s_in->sin_family != AF_INET) { … … 103 101 return NULL; 104 102 } 105 ad = s_in->sin_addr.s_addr; 106 #ifdef DEBUG 107 bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric); 108 #endif 109 if (ad == INADDR_ANY) { 110 if ((numeric & 0x0FFF) == 0) { 111 if (numeric & 0x8000) 112 return xstrdup("default"); 113 return xstrdup("*"); 114 } 115 } 103 nip = s_in->sin_addr.s_addr; 104 #ifdef DEBUG 105 bb_error_msg("rresolve: %08x mask:%08x num:%08x", (unsigned)nip, netmask, numeric); 106 #endif 116 107 if (numeric & 0x0FFF) 117 return xstrdup(inet_ntoa(s_in->sin_addr)); 118 119 if ((ad & (~netmask)) != 0 || (numeric & 0x4000)) 120 host = 1; 108 return xmalloc_sockaddr2dotted_noport((void*)s_in); 109 if (nip == INADDR_ANY) { 110 if (numeric & 0x8000) 111 return xstrdup("default"); 112 return xstrdup("*"); 113 } 114 115 is_host = ((nip & (~netmask)) != 0 || (numeric & 0x4000)); 116 121 117 pn = cache; 122 118 while (pn) { 123 if (pn-> addr.sin_addr.s_addr == ad && pn->host ==host) {119 if (pn->nip == nip && pn->is_host == is_host) { 124 120 #ifdef DEBUG 125 121 bb_error_msg("rresolve: found %s %08x in cache", 126 (host ? "host" : "net"), (unsigned)ad);122 (is_host ? "host" : "net"), (unsigned)nip); 127 123 #endif 128 124 return xstrdup(pn->name); … … 131 127 } 132 128 133 host_ad = ntohl(ad);134 129 name = NULL; 135 if (host) { 136 struct hostent *ent; 137 #ifdef DEBUG 138 bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad); 139 #endif 140 ent = gethostbyaddr((char *) &ad, 4, AF_INET); 141 if (ent) 142 name = xstrdup(ent->h_name); 130 if (is_host) { 131 #ifdef DEBUG 132 bb_error_msg("sockaddr2host_noport(%08x)", (unsigned)nip); 133 #endif 134 name = xmalloc_sockaddr2host_noport((void*)s_in); 143 135 } else if (ENABLE_FEATURE_ETC_NETWORKS) { 144 136 struct netent *np; 145 137 #ifdef DEBUG 146 bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad);147 #endif 148 np = getnetbyaddr( host_ad, AF_INET);138 bb_error_msg("getnetbyaddr(%08x)", (unsigned)ntohl(nip)); 139 #endif 140 np = getnetbyaddr(ntohl(nip), AF_INET); 149 141 if (np) 150 142 name = xstrdup(np->n_name); 151 143 } 152 144 if (!name) 153 name = xstrdup(inet_ntoa(s_in->sin_addr)); 145 name = xmalloc_sockaddr2dotted_noport((void*)s_in); 146 154 147 pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */ 155 148 pn->next = cache; 156 pn-> addr = *s_in;157 pn-> host =host;149 pn->nip = nip; 150 pn->is_host = is_host; 158 151 strcpy(pn->name, name); 159 152 cache = pn; 153 160 154 return name; 161 155 } … … 176 170 } 177 171 memcpy(sin6, ai->ai_addr, sizeof(*sin6)); 178 if (ai) 179 freeaddrinfo(ai); 172 freeaddrinfo(ai); 180 173 return 0; 181 174 } … … 190 183 char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) 191 184 { 192 char name[128];193 int s;194 195 185 if (sin6->sin6_family != AF_INET6) { 196 186 #ifdef DEBUG … … 202 192 } 203 193 if (numeric & 0x7FFF) { 204 inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name)); 205 return xstrdup(name); 194 return xmalloc_sockaddr2dotted_noport((void*)sin6); 206 195 } 207 196 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { … … 211 200 } 212 201 213 s = getnameinfo((struct sockaddr *) sin6, sizeof(*sin6), 214 name, sizeof(name), 215 /*serv,servlen:*/ NULL, 0, 216 0); 217 if (s != 0) { 218 bb_error_msg("getnameinfo failed"); 219 return NULL; 220 } 221 return xstrdup(name); 202 return xmalloc_sockaddr2host_noport((void*)sin6); 222 203 } 223 204 -
branches/3.3/mindi-busybox/libbb/inode_hash.c
r2725 r3621 12 12 13 13 typedef struct ino_dev_hash_bucket_struct { 14 struct ino_dev_hash_bucket_struct *next;15 14 ino_t ino; 16 15 dev_t dev; 16 /* 17 * Above fields can be 64-bit, while pointer may be 32-bit. 18 * Putting "next" field here may reduce size of this struct: 19 */ 20 struct ino_dev_hash_bucket_struct *next; 21 /* 22 * Reportedly, on cramfs a file and a dir can have same ino. 23 * Need to also remember "file/dir" bit: 24 */ 25 char isdir; /* bool */ 17 26 char name[1]; 18 27 } ino_dev_hashtable_bucket_t; 19 28 20 #define HASH_SIZE 311 /* Should be prime */21 #define hash_inode(i) (( i) % HASH_SIZE)29 #define HASH_SIZE 311u /* Should be prime */ 30 #define hash_inode(i) ((unsigned)(i) % HASH_SIZE) 22 31 23 32 /* array of [HASH_SIZE] elements */ … … 39 48 if ((bucket->ino == statbuf->st_ino) 40 49 && (bucket->dev == statbuf->st_dev) 50 && (bucket->isdir == !!S_ISDIR(statbuf->st_mode)) 41 51 ) { 42 52 return bucket->name; … … 53 63 ino_dev_hashtable_bucket_t *bucket; 54 64 55 i = hash_inode(statbuf->st_ino);56 65 if (!name) 57 66 name = ""; … … 59 68 bucket->ino = statbuf->st_ino; 60 69 bucket->dev = statbuf->st_dev; 70 bucket->isdir = !!S_ISDIR(statbuf->st_mode); 61 71 strcpy(bucket->name, name); 62 72 … … 64 74 ino_dev_hashtable = xzalloc(HASH_SIZE * sizeof(*ino_dev_hashtable)); 65 75 76 i = hash_inode(statbuf->st_ino); 66 77 bucket->next = ino_dev_hashtable[i]; 67 78 ino_dev_hashtable[i] = bucket; … … 73 84 { 74 85 int i; 75 ino_dev_hashtable_bucket_t *bucket ;86 ino_dev_hashtable_bucket_t *bucket, *next; 76 87 77 for (i = 0; ino_dev_hashtable && i < HASH_SIZE; i++) { 78 while (ino_dev_hashtable[i] != NULL) { 79 bucket = ino_dev_hashtable[i]->next; 80 free(ino_dev_hashtable[i]); 81 ino_dev_hashtable[i] = bucket; 88 if (!ino_dev_hashtable) 89 return; 90 91 for (i = 0; i < HASH_SIZE; i++) { 92 bucket = ino_dev_hashtable[i]; 93 94 while (bucket != NULL) { 95 next = bucket->next; 96 free(bucket); 97 bucket = next; 82 98 } 83 99 } -
branches/3.3/mindi-busybox/libbb/kernel_version.c
r3232 r3621 21 21 { 22 22 struct utsname name; 23 char * s, *t;23 char *t; 24 24 int i, r; 25 25 26 26 uname(&name); /* never fails */ 27 s= name.release;27 t = name.release; 28 28 r = 0; 29 29 for (i = 0; i < 3; i++) { 30 t = strtok( s, ".");30 t = strtok(t, "."); 31 31 r = r * 256 + (t ? atoi(t) : 0); 32 s= NULL;32 t = NULL; 33 33 } 34 34 return r; -
branches/3.3/mindi-busybox/libbb/lineedit.c
r3232 r3621 39 39 * 40 40 * PS1='\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] ' 41 * 42 * Unicode in PS1 is not fully supported: prompt length calulation is wrong, 43 * resulting in line wrap problems with long (multi-line) input. 44 * 45 * Multi-line PS1 (e.g. PS1="\n[\w]\n$ ") has problems with history 46 * browsing: up/down arrows result in scrolling. 47 * It stems from simplistic "cmdedit_y = cmdedit_prmt_len / cmdedit_termw" 48 * calculation of how many lines the prompt takes. 41 49 */ 42 #include "libbb.h" 50 #include "busybox.h" 51 #include "NUM_APPLETS.h" 43 52 #include "unicode.h" 44 53 #ifndef _POSIX_VDISABLE … … 134 143 135 144 const char *cmdedit_prompt; 136 #if ENABLE_FEATURE_EDITING_FANCY_PROMPT137 int num_ok_lines; /* = 1; */138 #endif139 145 140 146 #if ENABLE_USERNAME_OR_HOMEDIR … … 173 179 #define command_ps (S.command_ps ) 174 180 #define cmdedit_prompt (S.cmdedit_prompt ) 175 #define num_ok_lines (S.num_ok_lines )176 181 #define user_buf (S.user_buf ) 177 182 #define home_pwd_buf (S.home_pwd_buf ) … … 186 191 barrier(); \ 187 192 cmdedit_termw = 80; \ 188 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \189 193 IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \ 194 IF_FEATURE_EDITING_VI(delptr = delbuf;) \ 190 195 } while (0) 191 196 … … 669 674 static NOINLINE unsigned complete_username(const char *ud) 670 675 { 671 /* Using _r function to avoid pulling in static buffers */ 672 char line_buff[256]; 673 struct passwd pwd; 674 struct passwd *result; 676 struct passwd *pw; 675 677 unsigned userlen; 676 678 … … 679 681 680 682 setpwent(); 681 while ( !getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) {683 while ((pw = getpwent()) != NULL) { 682 684 /* Null usernames should result in all users as possible completions. */ 683 if (/* !userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) {684 add_match(xasprintf("~%s/", pw d.pw_name));685 } 686 } 687 endpwent(); 685 if (/* !ud[0] || */ is_prefixed_with(pw->pw_name, ud)) { 686 add_match(xasprintf("~%s/", pw->pw_name)); 687 } 688 } 689 endpwent(); /* don't keep password file open */ 688 690 689 691 return 1 + userlen; … … 774 776 pf_len = strlen(pfind); 775 777 778 #if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 779 if (type == FIND_EXE_ONLY) { 780 const char *p = applet_names; 781 782 while (*p) { 783 if (strncmp(pfind, p, pf_len) == 0) 784 add_match(xstrdup(p)); 785 while (*p++ != '\0') 786 continue; 787 } 788 } 789 #endif 790 776 791 for (i = 0; i < npaths; i++) { 777 792 DIR *dir; … … 792 807 continue; 793 808 /* match? */ 794 if ( strncmp(name_found, pfind, pf_len) != 0)809 if (!is_prefixed_with(name_found, pfind)) 795 810 continue; /* no */ 796 811 … … 1252 1267 line_input_t *n = xzalloc(sizeof(*n)); 1253 1268 n->flags = flags; 1269 #if MAX_HISTORY > 0 1254 1270 n->max_history = MAX_HISTORY; 1271 #endif 1255 1272 return n; 1256 1273 } … … 1259 1276 #if MAX_HISTORY > 0 1260 1277 1261 unsigned size_from_HISTFILESIZE(const char *hp)1278 unsigned FAST_FUNC size_from_HISTFILESIZE(const char *hp) 1262 1279 { 1263 1280 int size = MAX_HISTORY; … … 1312 1329 beep(); 1313 1330 return 0; 1331 } 1332 1333 /* Lists command history. Used by shell 'history' builtins */ 1334 void FAST_FUNC show_history(const line_input_t *st) 1335 { 1336 int i; 1337 1338 if (!st) 1339 return; 1340 for (i = 0; i < st->cnt_history; i++) 1341 printf("%4d %s\n", i, st->history[i]); 1314 1342 } 1315 1343 … … 1532 1560 save_history(str); 1533 1561 # endif 1534 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)1535 1562 } 1536 1563 … … 1754 1781 #endif 1755 1782 1783 /* Called just once at read_line_input() init time */ 1756 1784 #if !ENABLE_FEATURE_EDITING_FANCY_PROMPT 1757 1785 static void parse_and_put_prompt(const char *prmt_ptr) 1758 1786 { 1787 const char *p; 1759 1788 cmdedit_prompt = prmt_ptr; 1760 cmdedit_prmt_len = strlen(prmt_ptr); 1789 p = strrchr(prmt_ptr, '\n'); 1790 cmdedit_prmt_len = unicode_strwidth(p ? p+1 : prmt_ptr); 1761 1791 put_prompt(); 1762 1792 } … … 1764 1794 static void parse_and_put_prompt(const char *prmt_ptr) 1765 1795 { 1766 int prmt_len = 0; 1767 size_t cur_prmt_len = 0; 1796 int prmt_size = 0; 1797 char *prmt_mem_ptr = xzalloc(1); 1798 # if ENABLE_USERNAME_OR_HOMEDIR 1799 char *cwd_buf = NULL; 1800 # endif 1768 1801 char flg_not_length = '['; 1769 char *prmt_mem_ptr = xzalloc(1);1770 char *cwd_buf = xrealloc_getcwd_or_warn(NULL);1771 1802 char cbuf[2]; 1772 char c; 1773 char *pbuf; 1774 1775 cmdedit_prmt_len = 0; 1776 1777 if (!cwd_buf) { 1778 cwd_buf = (char *)bb_msg_unknown; 1779 } 1803 1804 /*cmdedit_prmt_len = 0; - already is */ 1780 1805 1781 1806 cbuf[1] = '\0'; /* never changes */ 1782 1807 1783 1808 while (*prmt_ptr) { 1809 char timebuf[sizeof("HH:MM:SS")]; 1784 1810 char *free_me = NULL; 1811 char *pbuf; 1812 char c; 1785 1813 1786 1814 pbuf = cbuf; 1787 1815 c = *prmt_ptr++; 1788 1816 if (c == '\\') { 1789 const char *cp = prmt_ptr;1817 const char *cp; 1790 1818 int l; 1791 1792 c = bb_process_escape_sequence(&prmt_ptr); 1819 /* 1820 * Supported via bb_process_escape_sequence: 1821 * \a ASCII bell character (07) 1822 * \e ASCII escape character (033) 1823 * \n newline 1824 * \r carriage return 1825 * \\ backslash 1826 * \nnn char with octal code nnn 1827 * Supported: 1828 * \$ if the effective UID is 0, a #, otherwise a $ 1829 * \w current working directory, with $HOME abbreviated with a tilde 1830 * Note: we do not support $PROMPT_DIRTRIM=n feature 1831 * \W basename of the current working directory, with $HOME abbreviated with a tilde 1832 * \h hostname up to the first '.' 1833 * \H hostname 1834 * \u username 1835 * \[ begin a sequence of non-printing characters 1836 * \] end a sequence of non-printing characters 1837 * \T current time in 12-hour HH:MM:SS format 1838 * \@ current time in 12-hour am/pm format 1839 * \A current time in 24-hour HH:MM format 1840 * \t current time in 24-hour HH:MM:SS format 1841 * (all of the above work as \A) 1842 * Not supported: 1843 * \! history number of this command 1844 * \# command number of this command 1845 * \j number of jobs currently managed by the shell 1846 * \l basename of the shell's terminal device name 1847 * \s name of the shell, the basename of $0 (the portion following the final slash) 1848 * \V release of bash, version + patch level (e.g., 2.00.0) 1849 * \d date in "Weekday Month Date" format (e.g., "Tue May 26") 1850 * \D{format} 1851 * format is passed to strftime(3). 1852 * An empty format results in a locale-specific time representation. 1853 * The braces are required. 1854 * Mishandled by bb_process_escape_sequence: 1855 * \v version of bash (e.g., 2.00) 1856 */ 1857 cp = prmt_ptr; 1858 c = *cp; 1859 if (c != 't') /* don't treat \t as tab */ 1860 c = bb_process_escape_sequence(&prmt_ptr); 1793 1861 if (prmt_ptr == cp) { 1794 1862 if (*cp == '\0') … … 1802 1870 break; 1803 1871 # endif 1872 case 'H': 1804 1873 case 'h': 1805 1874 pbuf = free_me = safe_gethostname(); 1806 *strchrnul(pbuf, '.') = '\0'; 1875 if (c == 'h') 1876 strchrnul(pbuf, '.')[0] = '\0'; 1807 1877 break; 1808 1878 case '$': 1809 1879 c = (geteuid() == 0 ? '#' : '$'); 1810 1880 break; 1881 case 'T': /* 12-hour HH:MM:SS format */ 1882 case '@': /* 12-hour am/pm format */ 1883 case 'A': /* 24-hour HH:MM format */ 1884 case 't': /* 24-hour HH:MM:SS format */ 1885 /* We show all of them as 24-hour HH:MM */ 1886 strftime_HHMMSS(timebuf, sizeof(timebuf), NULL)[-3] = '\0'; 1887 pbuf = timebuf; 1888 break; 1811 1889 # if ENABLE_USERNAME_OR_HOMEDIR 1812 case 'w': 1813 /* /home/user[/something] -> ~[/something] */ 1890 case 'w': /* current dir */ 1891 case 'W': /* basename of cur dir */ 1892 if (!cwd_buf) { 1893 cwd_buf = xrealloc_getcwd_or_warn(NULL); 1894 if (!cwd_buf) 1895 cwd_buf = (char *)bb_msg_unknown; 1896 else if (home_pwd_buf[0]) { 1897 char *after_home_user; 1898 1899 /* /home/user[/something] -> ~[/something] */ 1900 after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf); 1901 if (after_home_user 1902 && (*after_home_user == '/' || *after_home_user == '\0') 1903 ) { 1904 cwd_buf[0] = '~'; 1905 overlapping_strcpy(cwd_buf + 1, after_home_user); 1906 } 1907 } 1908 } 1814 1909 pbuf = cwd_buf; 1815 l = strlen(home_pwd_buf); 1816 if (l != 0 1817 && strncmp(home_pwd_buf, cwd_buf, l) == 0 1818 && (cwd_buf[l]=='/' || cwd_buf[l]=='\0') 1819 && strlen(cwd_buf + l) < PATH_MAX 1820 ) { 1821 pbuf = free_me = xasprintf("~%s", cwd_buf + l); 1822 } 1910 if (c == 'w') 1911 break; 1912 cp = strrchr(pbuf, '/'); 1913 if (cp) 1914 pbuf = (char*)cp + 1; 1823 1915 break; 1824 1916 # endif 1825 case 'W': 1826 pbuf = cwd_buf; 1827 cp = strrchr(pbuf, '/'); 1828 if (cp != NULL && cp != pbuf) 1829 pbuf += (cp-pbuf) + 1; 1830 break; 1831 case '!': 1832 pbuf = free_me = xasprintf("%d", num_ok_lines); 1833 break; 1834 case 'e': case 'E': /* \e \E = \033 */ 1835 c = '\033'; 1836 break; 1917 // bb_process_escape_sequence does this now: 1918 // case 'e': case 'E': /* \e \E = \033 */ 1919 // c = '\033'; 1920 // break; 1837 1921 case 'x': case 'X': { 1838 1922 char buf2[4]; … … 1856 1940 case '[': case ']': 1857 1941 if (c == flg_not_length) { 1858 flg_not_length = (flg_not_length == '[' ? ']' : '['); 1942 /* Toggle '['/']' hex 5b/5d */ 1943 flg_not_length ^= 6; 1859 1944 continue; 1860 1945 } … … 1864 1949 } /* if */ 1865 1950 cbuf[0] = c; 1866 cur_prmt_len = strlen(pbuf); 1867 prmt_len += cur_prmt_len; 1868 if (flg_not_length != ']') 1869 cmdedit_prmt_len += cur_prmt_len; 1870 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); 1951 { 1952 int n = strlen(pbuf); 1953 prmt_size += n; 1954 if (c == '\n') 1955 cmdedit_prmt_len = 0; 1956 else if (flg_not_length != ']') { 1957 #if 0 /*ENABLE_UNICODE_SUPPORT*/ 1958 /* Won't work, pbuf is one BYTE string here instead of an one Unicode char string. */ 1959 /* FIXME */ 1960 cmdedit_prmt_len += unicode_strwidth(pbuf); 1961 #else 1962 cmdedit_prmt_len += n; 1963 #endif 1964 } 1965 } 1966 prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_size+1), pbuf); 1871 1967 free(free_me); 1872 1968 } /* while */ 1873 1969 1970 # if ENABLE_USERNAME_OR_HOMEDIR 1874 1971 if (cwd_buf != (char *)bb_msg_unknown) 1875 1972 free(cwd_buf); 1973 # endif 1876 1974 cmdedit_prompt = prmt_mem_ptr; 1877 1975 put_prompt(); … … 1935 2033 if (cursor == 0) { /* otherwise it may be bogus */ 1936 2034 int col = ((ic >> 32) & 0x7fff) - 1; 1937 if (col > cmdedit_prmt_len) { 2035 /* 2036 * Is col > cmdedit_prmt_len? 2037 * If yes (terminal says cursor is farther to the right 2038 * of where we think it should be), 2039 * the prompt wasn't printed starting at col 1, 2040 * there was additional text before it. 2041 */ 2042 if ((int)(col - cmdedit_prmt_len) > 0) { 2043 /* Fix our understanding of current x position */ 1938 2044 cmdedit_x += (col - cmdedit_prmt_len); 1939 2045 while (cmdedit_x >= cmdedit_termw) { … … 2026 2132 const char *matched_history_line; 2027 2133 const char *saved_prompt; 2134 unsigned saved_prmt_len; 2028 2135 int32_t ic; 2029 2136 … … 2034 2141 /* Save and replace the prompt */ 2035 2142 saved_prompt = cmdedit_prompt; 2143 saved_prmt_len = cmdedit_prmt_len; 2036 2144 goto set_prompt; 2037 2145 … … 2109 2217 set_prompt: 2110 2218 cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf); 2111 cmdedit_prmt_len = strlen(cmdedit_prompt);2219 cmdedit_prmt_len = unicode_strwidth(cmdedit_prompt); 2112 2220 goto do_redraw; 2113 2221 } … … 2131 2239 free((char*)cmdedit_prompt); 2132 2240 cmdedit_prompt = saved_prompt; 2133 cmdedit_prmt_len = s trlen(cmdedit_prompt);2241 cmdedit_prmt_len = saved_prmt_len; 2134 2242 redraw(cmdedit_y, command_len - cursor); 2135 2243 … … 2161 2269 2162 2270 if (tcgetattr(STDIN_FILENO, &initial_settings) < 0 2163 || !(initial_settings.c_lflag & ECHO)2271 || (initial_settings.c_lflag & (ECHO|ICANON)) == ICANON 2164 2272 ) { 2165 /* Happens when e.g. stty -echo was run before */ 2273 /* Happens when e.g. stty -echo was run before. 2274 * But if ICANON is not set, we don't come here. 2275 * (example: interactive python ^Z-backgrounded, 2276 * tty is still in "raw mode"). 2277 */ 2166 2278 parse_and_put_prompt(prompt); 2167 2279 /* fflush_all(); - done by parse_and_put_prompt */ … … 2512 2624 * Often, Alt-<key> generates ESC-<key>. 2513 2625 */ 2514 ic = lineedit_read_key(read_key_buffer, timeout);2626 ic = lineedit_read_key(read_key_buffer, 50); 2515 2627 switch (ic) { 2516 2628 //case KEYCODE_LEFT: - bash doesn't do this … … 2699 2811 #endif 2700 2812 2701 if (command_len > 0) 2813 if (command_len > 0) { 2702 2814 remember_in_history(command); 2815 } 2703 2816 2704 2817 if (break_out > 0) { -
branches/3.3/mindi-busybox/libbb/login.c
r2725 r3621 17 17 18 18 static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y"; 19 static const char fmtstr_t[] ALIGN1 = "%H:%M:%S";20 19 21 20 void FAST_FUNC print_login_issue(const char *issue_file, const char *tty) … … 74 73 break; 75 74 case 't': 76 strftime (buf, sizeof(buf), fmtstr_t, localtime(&t));75 strftime_HHMMSS(buf, sizeof(buf), &t); 77 76 break; 78 77 case 'l': -
branches/3.3/mindi-busybox/libbb/loop.c
r3232 r3621 95 95 /* Open the file. Barf if this doesn't work. */ 96 96 mode = ro ? O_RDONLY : O_RDWR; 97 open_ffd: 97 98 ffd = open(file, mode); 98 99 if (ffd < 0) { 99 100 if (mode != O_RDONLY) { 100 101 mode = O_RDONLY; 101 ffd = open(file, mode);102 goto open_ffd; 102 103 } 103 if (ffd < 0) 104 return -errno; 104 return -errno; 105 105 } 106 106 107 107 /* Find a loop device. */ 108 108 try = *device ? *device : dev; 109 /* 1048575 is a max possible minor number in Linux circa 2010 */109 /* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */ 110 110 for (i = 0; rc && i < 1048576; i++) { 111 111 sprintf(dev, LOOP_FORMAT, i); … … 122 122 } 123 123 /* Ran out of block devices, return failure. */ 124 rc = - ENOENT;124 rc = -1; 125 125 break; 126 126 } … … 132 132 dfd = open(try, mode); 133 133 } 134 if (dfd < 0) 134 if (dfd < 0) { 135 if (errno == ENXIO) { 136 /* Happens if loop module is not loaded */ 137 rc = -1; 138 break; 139 } 135 140 goto try_again; 141 } 136 142 137 143 rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); … … 149 155 ioctl(dfd, LOOP_CLR_FD, 0); 150 156 } 151 152 /* If this block device already set up right, re-use it. 153 * (Yes this is racy, but associating two loop devices with the same 154 * file isn't pretty either. In general, mounting the same file twice 155 * without using losetup manually is problematic.) 156 */ 157 } else 158 if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 159 || offset != loopinfo.lo_offset 160 ) { 157 } else { 161 158 rc = -1; 162 159 } -
branches/3.3/mindi-busybox/libbb/make_directory.c
r3232 r3621 100 100 goto ret0; 101 101 } 102 } else { 103 if (flags & FILEUTILS_VERBOSE) { 104 printf("created directory: '%s'\n", path); 105 } 102 106 } 103 107 -
branches/3.3/mindi-busybox/libbb/match_fstype.c
r3232 r3621 18 18 { 19 19 int match = 1; 20 int len;21 20 22 21 if (!t_fstype) … … 28 27 } 29 28 30 len = strlen(mt->mnt_type);31 29 while (1) { 32 if (strncmp(mt->mnt_type, t_fstype, len) == 0 33 && (t_fstype[len] == '\0' || t_fstype[len] == ',') 30 char *after_mnt_type = is_prefixed_with(t_fstype, mt->mnt_type); 31 if (after_mnt_type 32 && (*after_mnt_type == '\0' || *after_mnt_type == ',') 34 33 ) { 35 34 return match; -
branches/3.3/mindi-busybox/libbb/messages.c
r3232 r3621 30 30 const char bb_msg_you_must_be_root[] ALIGN1 = "you must be root"; 31 31 const char bb_msg_requires_arg[] ALIGN1 = "%s requires an argument"; 32 const char bb_msg_invalid_arg [] ALIGN1 = "invalid argument '%s' to '%s'";32 const char bb_msg_invalid_arg_to[] ALIGN1 = "invalid argument '%s' to '%s'"; 33 33 const char bb_msg_standard_input[] ALIGN1 = "standard input"; 34 34 const char bb_msg_standard_output[] ALIGN1 = "standard output"; … … 44 44 45 45 46 const int const_int_1 = 1;46 //const int const_int_1 = 1; 47 47 /* explicitly = 0, otherwise gcc may make it a common variable 48 48 * and it will end up in bss */ … … 60 60 # endif 61 61 #endif 62 63 /* We use it for "global" data via *(struct global*)&bb_common_bufsiz1.64 * Since gcc insists on aligning struct global's members, it would be a pity65 * (and an alignment fault on some CPUs) to mess it up. */66 char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); -
branches/3.3/mindi-busybox/libbb/mode_string.c
r2725 r3621 88 88 /* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', 89 89 * and 'B' types don't appear to be available on linux. So I removed them. */ 90 static const char type_chars[16] = "?pc?d?b?-?l?s???";90 static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???"; 91 91 /********************************** 0123456789abcdef */ 92 static const char mode_chars[7] = "rwxSTst";92 static const char mode_chars[7] ALIGN1 = "rwxSTst"; 93 93 94 94 const char* FAST_FUNC bb_mode_string(mode_t mode) -
branches/3.3/mindi-busybox/libbb/obscure.c
r3232 r3621 77 77 78 78 /* clean up */ 79 memset(p, 0, size);79 nuke_str(p); 80 80 free(p); 81 81 … … 183 183 return 0; 184 184 } 185 186 #if ENABLE_UNIT_TEST 187 188 /* Test obscure_msg() instead of obscure() in order not to print anything. */ 189 190 static const struct passwd pw = { 191 .pw_name = (char *)"johndoe", 192 .pw_gecos = (char *)"John Doe", 193 }; 194 195 BBUNIT_DEFINE_TEST(obscure_weak_pass) 196 { 197 /* Empty password */ 198 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "", &pw)); 199 /* Pure numbers */ 200 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "23577315", &pw)); 201 /* Similar to pw_name */ 202 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "johndoe123%", &pw)); 203 /* Similar to pw_gecos, reversed */ 204 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "eoD nhoJ^44@", &pw)); 205 /* Similar to the old password */ 206 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "d4#21?'S", &pw)); 207 /* adjacent letters */ 208 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "qwerty123", &pw)); 209 /* Many similar chars */ 210 BBUNIT_ASSERT_NOTNULL(obscure_msg("Ad4#21?'S|", "^33Daaaaaa1", &pw)); 211 212 BBUNIT_ENDTEST; 213 } 214 215 BBUNIT_DEFINE_TEST(obscure_strong_pass) 216 { 217 BBUNIT_ASSERT_NULL(obscure_msg("Rt4##2&:'|", "}(^#rrSX3S*22", &pw)); 218 219 BBUNIT_ENDTEST; 220 } 221 222 #endif /* ENABLE_UNIT_TEST */ -
branches/3.3/mindi-busybox/libbb/parse_mode.c
r2725 r3621 16 16 #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 17 17 18 int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)18 int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode) 19 19 { 20 20 static const mode_t who_mask[] = { … … 47 47 tmp = strtoul(s, &e, 8); 48 48 if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ 49 return 0;49 return -1; 50 50 } 51 *current_mode = tmp; 52 return 1; 51 return tmp; 53 52 } 54 53 55 new_mode = *current_mode;54 new_mode = current_mode; 56 55 57 56 /* Note: we allow empty clauses, and hence empty modes. … … 72 71 wholist |= who_mask[(int)(p-who_chars)]; 73 72 if (!*++s) { 74 return 0;73 return -1; 75 74 } 76 75 goto WHO_LIST; … … 81 80 if ((*s != '+') && (*s != '-')) { 82 81 if (*s != '=') { 83 return 0;82 return -1; 84 83 } 85 84 /* Since op is '=', clear all bits corresponding to the … … 146 145 } 147 146 148 *current_mode = new_mode; 149 return 1; 147 return new_mode; 150 148 } -
branches/3.3/mindi-busybox/libbb/platform.c
r3232 r3621 18 18 #endif 19 19 20 #ifndef HAVE_USLEEP 21 int FAST_FUNC usleep(unsigned usec) 22 { 23 struct timespec ts; 24 ts.tv_sec = usec / 1000000u; 25 ts.tv_nsec = (usec % 1000000u) * 1000u; 26 /* 27 * If a signal has non-default handler, nanosleep returns early. 28 * Our version of usleep doesn't return early 29 * if interrupted by such signals: 30 * 31 */ 32 while (nanosleep(&ts, &ts) != 0) 33 continue; 34 return 0; 35 } 36 #endif 37 20 38 #ifndef HAVE_VASPRINTF 21 39 int FAST_FUNC vasprintf(char **string_ptr, const char *format, va_list p) … … 29 47 va_end(p); 30 48 49 /* Note: can't use xstrdup/xmalloc, they call vasprintf (us) on failure! */ 50 31 51 if (r < 128) { 32 52 va_end(p2); 33 *string_ptr = xstrdup(buf);34 return r;35 } 36 37 *string_ptr = xmalloc(r+1);38 r = vsnprintf(*string_ptr, r+1, format, p2);53 *string_ptr = strdup(buf); 54 return (*string_ptr ? r : -1); 55 } 56 57 *string_ptr = malloc(r+1); 58 r = (*string_ptr ? vsnprintf(*string_ptr, r+1, format, p2) : -1); 39 59 va_end(p2); 40 60 … … 175 195 } 176 196 #endif 197 198 #ifndef HAVE_TTYNAME_R 199 int ttyname_r(int fd, char *buf, size_t buflen) 200 { 201 int r; 202 char path[sizeof("/proc/self/fd/%d") + sizeof(int)*3]; 203 204 if (!isatty(fd)) 205 return errno == EINVAL ? ENOTTY : errno; 206 sprintf(path, "/proc/self/fd/%d", fd); 207 r = readlink(path, buf, buflen); 208 if (r < 0) 209 return errno; 210 if (r >= buflen) 211 return ERANGE; 212 buf[r] = '\0'; 213 return 0; 214 } 215 #endif -
branches/3.3/mindi-busybox/libbb/printable.c
r2725 r3621 33 33 fputc(ch, file); 34 34 } 35 36 void FAST_FUNC visible(unsigned ch, char *buf, int flags) 37 { 38 if (ch == '\t' && !(flags & VISIBLE_SHOW_TABS)) { 39 goto raw; 40 } 41 if (ch == '\n') { 42 if (flags & VISIBLE_ENDLINE) 43 *buf++ = '$'; 44 } else { 45 if (ch >= 128) { 46 ch -= 128; 47 *buf++ = 'M'; 48 *buf++ = '-'; 49 } 50 if (ch < 32 || ch == 127) { 51 *buf++ = '^'; 52 ch ^= 0x40; 53 } 54 } 55 raw: 56 *buf++ = ch; 57 *buf = '\0'; 58 } -
branches/3.3/mindi-busybox/libbb/printable_string.c
r2725 r3621 12 12 const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) 13 13 { 14 static char *saved[4];15 static unsigned cur_saved; /* = 0 */16 17 14 char *dst; 18 15 const char *s; … … 57 54 } 58 55 #endif 59 60 free(saved[cur_saved]); 61 saved[cur_saved] = dst; 62 cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); 63 64 return dst; 56 return auto_string(dst); 65 57 } -
branches/3.3/mindi-busybox/libbb/procps.c
r3232 r3621 206 206 // ..... 207 207 208 char *tp = buf, *p;208 char *tp, *p; 209 209 210 210 #define SCAN(S, X) \ 211 if ( strncmp(tp, S, sizeof(S)-1) == 0) {\212 tp = skip_whitespace(tp + sizeof(S)-1);\211 if ((tp = is_prefixed_with(buf, S)) != NULL) { \ 212 tp = skip_whitespace(tp); \ 213 213 total->X += currec.X = fast_strtoul_10(&tp); \ 214 214 continue; \ … … 248 248 tp = skip_whitespace(skip_fields(tp, 4)); 249 249 // filter out /dev/something (something != zero) 250 if ( strncmp(tp, "/dev/", 5) != 0|| strcmp(tp, "/dev/zero\n") == 0) {250 if (!is_prefixed_with(tp, "/dev/") || strcmp(tp, "/dev/zero\n") == 0) { 251 251 if (currec.smap_mode[1] == 'w') { 252 252 currec.mapped_rw = currec.smap_size; … … 284 284 #endif 285 285 286 void BUG_comm_size(void);287 286 procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) 288 287 { … … 386 385 continue;*/ 387 386 cp[0] = '\0'; 388 if (sizeof(sp->comm) < 16) 389 BUG_comm_size(); 387 BUILD_BUG_ON(sizeof(sp->comm) < 16); 390 388 comm1 = strchr(buf, '('); 391 389 /*if (comm1)*/ … … 498 496 char *tp; 499 497 #define SCAN_TWO(str, name, statement) \ 500 if ( strncmp(buf, str, sizeof(str)-1) == 0) { \501 tp = skip_whitespace( buf + sizeof(str)-1); \498 if ((tp = is_prefixed_with(buf, str)) != NULL) { \ 499 tp = skip_whitespace(tp); \ 502 500 sscanf(tp, "%u", &sp->name); \ 503 501 statement; \ … … 555 553 if (flags & PSSCAN_ARGVN) { 556 554 sp->argv_len = n; 557 sp->argv0 = xmalloc(n + 1); 558 memcpy(sp->argv0, buf, n + 1); 555 sp->argv0 = xmemdup(buf, n + 1); 559 556 /* sp->argv0[n] = '\0'; - buf has it */ 560 557 } else { … … 592 589 sz--; 593 590 } 591 if (base[0] == '-') /* "-sh" (login shell)? */ 592 base++; 594 593 595 594 /* If comm differs from argv0, prepend "{comm} ". 596 595 * It allows to see thread names set by prctl(PR_SET_NAME). 597 596 */ 598 if ( base[0] == '-') /* "-sh" (login shell)? */599 base++;597 if (!comm) 598 return; 600 599 comm_len = strlen(comm); 601 600 /* Why compare up to comm_len, not COMM_LEN-1? … … 615 614 buf[col - 1] = '\0'; 616 615 } 617 618 616 } else { 619 snprintf(buf, col, "[%s]", comm );617 snprintf(buf, col, "[%s]", comm ? comm : "?"); 620 618 } 621 619 } -
branches/3.3/mindi-busybox/libbb/progress.c
r3232 r3621 45 45 STALLTIME = 5 46 46 }; 47 48 static unsigned int get_tty2_width(void)49 {50 unsigned width;51 get_terminal_width_height(2, &width, NULL);52 return width;53 }54 47 55 48 void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile) … … 81 74 uoff_t beg_and_transferred; 82 75 unsigned since_last_update, elapsed; 83 int barlength;76 int notty; 84 77 int kiloscale; 85 78 … … 138 131 } 139 132 133 notty = !isatty(STDERR_FILENO); 134 140 135 if (ENABLE_UNICODE_SUPPORT) 141 fprintf(stderr, "\r%s" , p->curfile);136 fprintf(stderr, "\r%s" + notty, p->curfile); 142 137 else 143 fprintf(stderr, "\r%-20.20s" , p->curfile);138 fprintf(stderr, "\r%-20.20s" + notty, p->curfile); 144 139 145 140 beg_and_transferred = beg_size + transferred; 146 141 147 142 if (totalsize != 0) { 143 int barlength; 148 144 unsigned ratio = 100 * beg_and_transferred / totalsize; 149 145 fprintf(stderr, "%4u%%", ratio); 150 146 151 barlength = get_t ty2_width() - 49;147 barlength = get_terminal_width(2) - 49; 152 148 if (barlength > 0) { 153 149 /* god bless gcc for variable arrays :) */ … … 205 201 fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60); 206 202 } 203 if (notty) 204 fputc('\n', stderr); 207 205 } -
branches/3.3/mindi-busybox/libbb/pw_encrypt.c
r3232 r3621 10 10 #include "libbb.h" 11 11 12 /* static const uint8_t ascii64[] =12 /* static const uint8_t ascii64[] ALIGN1 = 13 13 * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 14 14 */ … … 53 53 int len = 2/2; 54 54 char *salt_ptr = salt; 55 if (algo[0] != 'd') { /* not des */ 55 56 /* Standard chpasswd uses uppercase algos ("MD5", not "md5"). 57 * Need to be case-insensitive in the code below. 58 */ 59 if ((algo[0]|0x20) != 'd') { /* not des */ 56 60 len = 8/2; /* so far assuming md5 */ 57 61 *salt_ptr++ = '$'; … … 59 63 *salt_ptr++ = '$'; 60 64 #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA 61 if ( algo[0]== 's') { /* sha */62 salt[1] = '5' + (strc mp(algo, "sha512") == 0);65 if ((algo[0]|0x20) == 's') { /* sha */ 66 salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); 63 67 len = 16/2; 64 68 } … … 143 147 char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) 144 148 { 145 return xstrdup(crypt(clear, salt)); 149 char *s; 150 151 s = crypt(clear, salt); 152 /* 153 * glibc used to return "" on malformed salts (for example, ""), 154 * but since 2.17 it returns NULL. 155 */ 156 return xstrdup(s ? s : ""); 146 157 } 147 158 -
branches/3.3/mindi-busybox/libbb/pw_encrypt_md5.c
r2725 r3621 87 87 /* Get the length of the salt including "$1$" */ 88 88 sl = 3; 89 while (s alt[sl] && salt[sl] != '$' && sl < (3 + 8))89 while (sl < (3 + 8) && salt[sl] && salt[sl] != '$') 90 90 sl++; 91 91 -
branches/3.3/mindi-busybox/libbb/read_printf.c
r3232 r3621 46 46 * Thankfully, poll() doesn't care about O_NONBLOCK flag. 47 47 */ 48 ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count , int loop_on_EINTR)48 ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count) 49 49 { 50 50 struct pollfd pfd[1]; … … 52 52 53 53 while (1) { 54 n = loop_on_EINTR ? safe_read(fd, buf, count) :read(fd, buf, count);54 n = safe_read(fd, buf, count); 55 55 if (n >= 0 || errno != EAGAIN) 56 56 return n; … … 59 59 pfd[0].events = POLLIN; 60 60 /* note: safe_poll pulls in printf */ 61 loop_on_EINTR ? safe_poll(pfd, 1, -1) :poll(pfd, 1, -1);61 safe_poll(pfd, 1, -1); 62 62 } 63 63 } … … 82 82 sz += 128; 83 83 } 84 if (nonblock_immune_read(fd, p, 1 , /*loop_on_EINTR:*/ 1) != 1) {84 if (nonblock_immune_read(fd, p, 1) != 1) { 85 85 /* EOF/error */ 86 86 if (p == buf) { /* we read nothing */ -
branches/3.3/mindi-busybox/libbb/remove_file.c
r3232 r3621 79 79 } 80 80 81 if (flags & FILEUTILS_VERBOSE) { 82 printf("removed directory: '%s'\n", path); 83 } 84 81 85 return status; 82 86 } … … 99 103 } 100 104 105 if (flags & FILEUTILS_VERBOSE) { 106 printf("removed '%s'\n", path); 107 } 108 101 109 return 0; 102 110 } -
branches/3.3/mindi-busybox/libbb/rtc.c
r2725 r3621 23 23 24 24 while (fgets(buffer, sizeof(buffer), f)) { 25 if ( strncmp(buffer, "UTC", 3) == 0) {25 if (is_prefixed_with(buffer, "UTC")) { 26 26 utc = 1; 27 27 break; … … 34 34 } 35 35 36 /* rtc opens are exclusive. 37 * Try to run two "hwclock -w" at the same time to see it. 38 * Users wouldn't expect that to fail merely because /dev/rtc 39 * was momentarily busy, let's try a bit harder on errno == EBUSY. 40 */ 41 static int open_loop_on_busy(const char *name, int flags) 42 { 43 int rtc; 44 /* 45 * Tested with two parallel "hwclock -w" loops. 46 * With try = 10, no failures with 2x1000000 loop iterations. 47 */ 48 int try = 1000 / 20; 49 again: 50 errno = 0; 51 rtc = open(name, flags); 52 if (errno == EBUSY) { 53 usleep(20 * 1000); 54 if (--try != 0) 55 goto again; 56 /* EBUSY. Last try, exit on error instead of returning -1 */ 57 return xopen(name, flags); 58 } 59 return rtc; 60 } 61 62 /* Never fails */ 36 63 int FAST_FUNC rtc_xopen(const char **default_rtc, int flags) 37 64 { 38 65 int rtc; 66 const char *name = 67 "/dev/rtc""\0" 68 "/dev/rtc0""\0" 69 "/dev/misc/rtc""\0"; 39 70 40 if (!*default_rtc) { 41 *default_rtc = "/dev/rtc"; 42 rtc = open(*default_rtc, flags); 71 if (!*default_rtc) 72 goto try_name; 73 name = ""; /*else: we have rtc name, don't try other names */ 74 75 for (;;) { 76 rtc = open_loop_on_busy(*default_rtc, flags); 43 77 if (rtc >= 0) 44 78 return rtc; 45 *default_rtc = "/dev/rtc0";46 rtc =open(*default_rtc, flags);47 if (rtc >= 0) 48 return rtc;49 *default_rtc = "/dev/misc/rtc";79 if (!name[0]) 80 return xopen(*default_rtc, flags); 81 try_name: 82 *default_rtc = name; 83 name += strlen(name) + 1; 50 84 } 51 52 return xopen(*default_rtc, flags);53 85 } 54 86 -
branches/3.3/mindi-busybox/libbb/skip_whitespace.c
r2725 r3621 34 34 char* FAST_FUNC skip_dev_pfx(const char *tty_name) 35 35 { 36 if ( strncmp(tty_name, "/dev/", 5) == 0)36 if (is_prefixed_with(tty_name, "/dev/")) 37 37 tty_name += 5; 38 38 return (char*)tty_name; -
branches/3.3/mindi-busybox/libbb/speed_table.c
r2725 r3621 11 11 12 12 struct speed_map { 13 #if defined __FreeBSD__ 14 /* On FreeBSD, B<num> constants don't fit into a short */ 15 unsigned speed; 16 #else 13 17 unsigned short speed; 18 #endif 14 19 unsigned short value; 15 20 }; -
branches/3.3/mindi-busybox/libbb/strrstr.c
r2725 r3621 8 8 */ 9 9 10 #ifdef __DO_STRRSTR_TEST11 #include <stdlib.h>12 #include <string.h>13 #include <stdio.h>14 #else15 10 #include "libbb.h" 16 #endif17 11 18 12 /* … … 35 29 } 36 30 37 #ifdef __DO_STRRSTR_TEST 38 int main(int argc, char **argv) 31 #if ENABLE_UNIT_TEST 32 33 BBUNIT_DEFINE_TEST(strrstr) 39 34 { 40 35 static const struct { … … 60 55 while (i < sizeof(test_array) / sizeof(test_array[0])) { 61 56 const char *r = strrstr(test_array[i].h, test_array[i].n); 62 printf("'%s' vs. '%s': '%s' - ", test_array[i].h, test_array[i].n, r);63 57 if (r == NULL) 64 58 r = test_array[i].h - 1; 65 printf("%s\n", r == test_array[i].h + test_array[i].pos ? "PASSED" : "FAILED");59 BBUNIT_ASSERT_EQ(r, test_array[i].h + test_array[i].pos); 66 60 i++; 67 61 } 68 62 69 return 0;63 BBUNIT_ENDTEST; 70 64 } 71 #endif 65 66 #endif /* ENABLE_UNIT_TEST */ -
branches/3.3/mindi-busybox/libbb/time.c
r3232 r3621 24 24 &ptm->tm_hour, 25 25 &ptm->tm_min, 26 &end) >= 2) { 26 &end) >= 2 27 ) { 27 28 /* no adjustments needed */ 28 29 } else … … 31 32 &ptm->tm_mon, &ptm->tm_mday, 32 33 &ptm->tm_hour, &ptm->tm_min, 33 &end) >= 4) { 34 &end) >= 4 35 ) { 34 36 /* Adjust month from 1-12 to 0-11 */ 35 37 ptm->tm_mon -= 1; … … 39 41 &ptm->tm_mon, &ptm->tm_mday, 40 42 &ptm->tm_hour, &ptm->tm_min, 41 &end) >= 5) { 42 ptm->tm_year -= 1900; /* Adjust years */ 43 ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ 44 } else 43 &end) >= 5 45 44 /* yyyy-mm-dd HH:MM */ 46 if (sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year,45 || sscanf(date_str, "%u-%u-%u %u:%u%c", &ptm->tm_year, 47 46 &ptm->tm_mon, &ptm->tm_mday, 48 47 &ptm->tm_hour, &ptm->tm_min, 49 &end) >= 5) { 48 &end) >= 5 49 ) { 50 50 ptm->tm_year -= 1900; /* Adjust years */ 51 51 ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ … … 59 59 } else 60 60 #endif 61 //TODO: coreutils 6.9 also accepts "yyyy-mm-dd HH" (no minutes)62 61 { 63 62 bb_error_msg_and_die(bb_msg_invalid_date, date_str); … … 69 68 /* else end != NUL and we error out */ 70 69 } 71 } else if (date_str[0] == '@') { 70 } else 71 if (strchr(date_str, '-') 72 /* Why strchr('-') check? 73 * sscanf below will trash ptm->tm_year, this breaks 74 * if parse_str is "10101010" (iow, "MMddhhmm" form) 75 * because we destroy year. Do these sscanf 76 * only if we saw a dash in parse_str. 77 */ 78 /* yyyy-mm-dd HH */ 79 && (sscanf(date_str, "%u-%u-%u %u%c", &ptm->tm_year, 80 &ptm->tm_mon, &ptm->tm_mday, 81 &ptm->tm_hour, 82 &end) >= 4 83 /* yyyy-mm-dd */ 84 || sscanf(date_str, "%u-%u-%u%c", &ptm->tm_year, 85 &ptm->tm_mon, &ptm->tm_mday, 86 &end) >= 3 87 ) 88 ) { 89 ptm->tm_year -= 1900; /* Adjust years */ 90 ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ 91 } else 92 if (date_str[0] == '@') { 72 93 time_t t = bb_strtol(date_str + 1, NULL, 10); 73 94 if (!errno) { … … 166 187 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 167 188 } 189 ptm->tm_sec = 0; /* assume zero if [.SS] is not given */ 168 190 if (end == '.') { 169 191 /* xxx.SS */ … … 188 210 } 189 211 212 static char* strftime_fmt(char *buf, unsigned len, time_t *tp, const char *fmt) 213 { 214 time_t t; 215 if (!tp) { 216 tp = &t; 217 time(tp); 218 } 219 /* Returns pointer to NUL */ 220 return buf + strftime(buf, len, fmt, localtime(tp)); 221 } 222 223 char* FAST_FUNC strftime_HHMMSS(char *buf, unsigned len, time_t *tp) 224 { 225 return strftime_fmt(buf, len, tp, "%H:%M:%S"); 226 } 227 228 char* FAST_FUNC strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) 229 { 230 return strftime_fmt(buf, len, tp, "%Y-%m-%d %H:%M:%S"); 231 } 232 190 233 #if ENABLE_MONOTONIC_SYSCALL 191 234 -
branches/3.3/mindi-busybox/libbb/u_signal_names.c
r3232 r3621 20 20 * HPPA: SIGSTKFLT == 36. */ 21 21 22 static const char signals[][7] = {22 static const char signals[][7] ALIGN1 = { 23 23 // SUSv3 says kill must support these, and specifies the numerical values, 24 24 // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html -
branches/3.3/mindi-busybox/libbb/udp_io.c
r3232 r3621 17 17 { 18 18 #ifdef IP_PKTINFO 19 setsockopt (fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int));19 setsockopt_1(fd, IPPROTO_IP, IP_PKTINFO); 20 20 #endif 21 21 #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) 22 setsockopt (fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int));22 setsockopt_1(fd, IPPROTO_IPV6, IPV6_PKTINFO); 23 23 #endif 24 24 } -
branches/3.3/mindi-busybox/libbb/unicode.c
r3232 r3621 29 29 size_t width; 30 30 31 /* We pass "" instead of "C" because some libc's have 32 * non-ASCII default locale for setlocale("") call 33 * (this allows users of such libc to have Unicoded 34 * system without having to mess with env). 35 * 36 * We set LC_CTYPE because (a) we may be called with $LC_CTYPE 37 * value in LANG, not with $LC_ALL, (b) internationalized 38 * LC_NUMERIC and LC_TIME are more PITA than benefit 39 * (for one, some utilities have hard time with comma 40 * used as a fractional separator). 41 */ 31 42 //TODO: avoid repeated calls by caching last string? 32 setlocale(LC_ ALL, (LANG && LANG[0]) ? LANG : "C");43 setlocale(LC_CTYPE, LANG ? LANG : ""); 33 44 34 45 /* In unicode, this is a one character string */ 35 // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused 36 width = mbstowcs(NULL, unicode_0x394, INT_MAX); 46 width = unicode_strlen(unicode_0x394); 37 47 unicode_status = (width == 1 ? UNICODE_ON : UNICODE_OFF); 38 48 } … … 40 50 void FAST_FUNC init_unicode(void) 41 51 { 42 if (unicode_status == UNICODE_UNKNOWN) 43 reinit_unicode(getenv("LANG")); 52 /* Some people set only $LC_CTYPE, not $LC_ALL, because they want 53 * only Unicode to be activated on their system, not the whole 54 * shebang of wrong decimal points, strange date formats and so on. 55 */ 56 if (unicode_status == UNICODE_UNKNOWN) { 57 char *s = getenv("LC_ALL"); 58 if (!s) s = getenv("LC_CTYPE"); 59 if (!s) s = getenv("LANG"); 60 reinit_unicode(s); 61 } 44 62 } 45 63 … … 59 77 void FAST_FUNC init_unicode(void) 60 78 { 61 if (unicode_status == UNICODE_UNKNOWN) 62 reinit_unicode(getenv("LANG")); 79 if (unicode_status == UNICODE_UNKNOWN) { 80 char *s = getenv("LC_ALL"); 81 if (!s) s = getenv("LC_CTYPE"); 82 if (!s) s = getenv("LANG"); 83 reinit_unicode(s); 84 } 63 85 } 64 86 # endif … … 964 986 /* The rest is mostly same for libc and for "homegrown" support */ 965 987 966 #if 0 // UNUSED967 988 size_t FAST_FUNC unicode_strlen(const char *string) 968 989 { … … 972 993 return width; 973 994 } 974 #endif975 995 976 996 size_t FAST_FUNC unicode_strwidth(const char *string) -
branches/3.3/mindi-busybox/libbb/update_passwd.c
r2725 r3621 63 63 or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd 64 64 65 8) delete a user from all groups: update_passwd(FILE, NULL, NULL, MEMBER) 66 65 67 This function does not validate the arguments fed to it 66 68 so the calling program should take care of that. … … 83 85 char *sfx_char; 84 86 char *name_colon; 85 unsigned user_len;86 87 int old_fd; 87 88 int new_fd; … … 100 101 return ret; 101 102 102 check_selinux_update_passwd(name); 103 if (name) 104 check_selinux_update_passwd(name); 103 105 104 106 /* New passwd file, "/etc/passwd+" for now */ 105 107 fnamesfx = xasprintf("%s+", filename); 106 108 sfx_char = &fnamesfx[strlen(fnamesfx)-1]; 107 name_colon = xasprintf("%s:", name); 108 user_len = strlen(name_colon); 109 name_colon = xasprintf("%s:", name ? name : ""); 109 110 110 111 if (shadow) … … 168 169 if (!line) /* EOF/error */ 169 170 break; 170 if (strncmp(name_colon, line, user_len) != 0) { 171 172 if (!name && member) { 173 /* Delete member from all groups */ 174 /* line is "GROUP:PASSWD:[member1[,member2]...]" */ 175 unsigned member_len = strlen(member); 176 char *list = strrchr(line, ':'); 177 while (list) { 178 list++; 179 next_list_element: 180 if (is_prefixed_with(list, member)) { 181 char c; 182 changed_lines++; 183 c = list[member_len]; 184 if (c == '\0') { 185 if (list[-1] == ',') 186 list--; 187 *list = '\0'; 188 break; 189 } 190 if (c == ',') { 191 overlapping_strcpy(list, list + member_len + 1); 192 goto next_list_element; 193 } 194 changed_lines--; 195 } 196 list = strchr(list, ','); 197 } 171 198 fprintf(new_fp, "%s\n", line); 172 199 goto next; 173 200 } 174 201 202 cp = is_prefixed_with(line, name_colon); 203 if (!cp) { 204 fprintf(new_fp, "%s\n", line); 205 goto next; 206 } 207 175 208 /* We have a match with "name:"... */ 176 cp = line + user_len; /* move past name:*/209 /* cp points past "name:" */ 177 210 178 211 #if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP -
branches/3.3/mindi-busybox/libbb/utmp.c
r3232 r3621 17 17 void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname) 18 18 { 19 struct utmp utent;19 struct utmpx utent; 20 20 char *id; 21 21 unsigned width; … … 46 46 strncpy(id, tty_name, width); 47 47 48 touch(_PATH_UTMP );49 //utmp name(_PATH_UTMP);50 setut ent();48 touch(_PATH_UTMPX); 49 //utmpxname(_PATH_UTMPX); 50 setutxent(); 51 51 /* Append new one (hopefully, unless we collide on ut_id) */ 52 putut line(&utent);53 endut ent();52 pututxline(&utent); 53 endutxent(); 54 54 55 55 #if ENABLE_FEATURE_WTMP 56 56 /* "man utmp" says wtmp file should *not* be created automagically */ 57 57 /*touch(bb_path_wtmp_file);*/ 58 updwtmp (bb_path_wtmp_file, &utent);58 updwtmpx(bb_path_wtmp_file, &utent); 59 59 #endif 60 60 } … … 65 65 void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname) 66 66 { 67 struct utmp utent;68 struct utmp *utp;67 struct utmpx utent; 68 struct utmpx *utp; 69 69 70 touch(_PATH_UTMP );71 //utmp name(_PATH_UTMP);72 setut ent();70 touch(_PATH_UTMPX); 71 //utmpxname(_PATH_UTMPX); 72 setutxent(); 73 73 74 74 /* Did init/getty/telnetd/sshd/... create an entry for us? 75 75 * It should be (new_type-1), but we'd also reuse 76 76 * any other potentially stale xxx_PROCESS entry */ 77 while ((utp = getut ent()) != NULL) {77 while ((utp = getutxent()) != NULL) { 78 78 if (utp->ut_pid == pid 79 79 // && ut->ut_line[0] … … 89 89 memset(utp->ut_host, 0, sizeof(utp->ut_host)); 90 90 } 91 /* NB: putut line (see later) searches for matching utent92 * using getut id(utent) - we must not change ut_id91 /* NB: pututxline (see later) searches for matching utxent 92 * using getutxid(utent) - we must not change ut_id 93 93 * if we want *exactly this* record to be overwritten! 94 94 */ … … 96 96 } 97 97 } 98 //endut ent(); - no need, pututline can deal with (and actually likes)98 //endutxent(); - no need, pututxline can deal with (and actually likes) 99 99 //the situation when utmp file is positioned on found record 100 100 … … 103 103 write_new_utmp(pid, new_type, tty_name, username, hostname); 104 104 else 105 endut ent();105 endutxent(); 106 106 return; 107 107 } 108 108 109 /* Make a copy. We can't use *utp, putut line's internal getutid109 /* Make a copy. We can't use *utp, pututxline's internal getutxid 110 110 * will overwrite it before it is used! */ 111 111 utent = *utp; … … 121 121 122 122 /* Update, or append new one */ 123 //setut ent();124 putut line(&utent);125 endut ent();123 //setutxent(); 124 pututxline(&utent); 125 endutxent(); 126 126 127 127 #if ENABLE_FEATURE_WTMP 128 128 /* "man utmp" says wtmp file should *not* be created automagically */ 129 129 /*touch(bb_path_wtmp_file);*/ 130 updwtmp (bb_path_wtmp_file, &utent);130 updwtmpx(bb_path_wtmp_file, &utent); 131 131 #endif 132 132 } 133 134 /* man utmp: 135 * When init(8) finds that a process has exited, it locates its utmp entry 136 * by ut_pid, sets ut_type to DEAD_PROCESS, and clears ut_user, ut_host 137 * and ut_time with null bytes. 138 * [same applies to other processes which maintain utmp entries, like telnetd] 139 * 140 * We do not bother actually clearing fields: 141 * it might be interesting to know who was logged in and from where 142 */ 143 void FAST_FUNC update_utmp_DEAD_PROCESS(pid_t pid) 144 { 145 update_utmp(pid, DEAD_PROCESS, NULL, NULL, NULL); 146 } -
branches/3.3/mindi-busybox/libbb/verror_msg.c
r2725 r3621 12 12 #endif 13 13 14 #if ENABLE_FEATURE_SYSLOG 15 smallint syslog_level = LOG_ERR; 16 #endif 14 17 smallint logmode = LOGMODE_STDIO; 15 18 const char *msg_eol = "\n"; … … 18 21 { 19 22 char *msg, *msg1; 23 char stack_msg[80]; 20 24 int applet_len, strerr_len, msgeol_len, used; 21 25 … … 25 29 if (!s) /* nomsg[_and_die] uses NULL fmt */ 26 30 s = ""; /* some libc don't like printf(NULL) */ 31 32 applet_len = strlen(applet_name) + 2; /* "applet: " */ 33 strerr_len = strerr ? strlen(strerr) : 0; 34 msgeol_len = strlen(msg_eol); 35 36 /* This costs ~90 bytes of code, but avoids costly 37 * malloc()[in vasprintf]+realloc()+memmove()+free() in 99% of cases. 38 * ~40% speedup. 39 */ 40 if ((int)sizeof(stack_msg) - applet_len > 0) { 41 va_list p2; 42 43 /* It is not portable to use va_list twice, need to va_copy it */ 44 va_copy(p2, p); 45 used = vsnprintf(stack_msg + applet_len, (int)sizeof(stack_msg) - applet_len, s, p2); 46 va_end(p2); 47 msg = stack_msg; 48 used += applet_len; 49 if (used < (int)sizeof(stack_msg) - 3 - msgeol_len - strerr_len) 50 goto add_pfx_and_sfx; 51 } 27 52 28 53 used = vasprintf(&msg, s, p); … … 35 60 * children can produce log messages simultaneously. */ 36 61 37 applet_len = strlen(applet_name) + 2; /* "applet: " */38 strerr_len = strerr ? strlen(strerr) : 0;39 msgeol_len = strlen(msg_eol);40 62 /* can't use xrealloc: it calls error_msg on failure, 41 63 * that may result in a recursion */ … … 50 72 memmove(msg + applet_len, msg, used); 51 73 used += applet_len; 74 add_pfx_and_sfx: 52 75 strcpy(msg, applet_name); 53 76 msg[applet_len - 2] = ':'; … … 71 94 #if ENABLE_FEATURE_SYSLOG 72 95 if (logmode & LOGMODE_SYSLOG) { 73 syslog( LOG_ERR, "%s", msg + applet_len);96 syslog(syslog_level, "%s", msg + applet_len); 74 97 } 75 98 #endif 76 free(msg); 99 if (msg != stack_msg) 100 free(msg); 77 101 } 78 102 -
branches/3.3/mindi-busybox/libbb/vfork_daemon_rexec.c
r3232 r3621 70 70 71 71 #if ENABLE_FEATURE_PREFER_APPLETS 72 static jmp_buf die_jmp; 73 static void jump(void) 74 { 75 /* Special case. We arrive here if NOFORK applet 76 * calls xfunc, which then decides to die. 77 * We don't die, but jump instead back to caller. 78 * NOFORK applets still cannot carelessly call xfuncs: 79 * p = xmalloc(10); 80 * q = xmalloc(10); // BUG! if this dies, we leak p! 81 */ 82 /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). 83 * This works because exitcodes are bytes, 84 * run_nofork_applet() ensures that by "& 0xff" */ 85 longjmp(die_jmp, xfunc_error_retval | 0x100); 86 } 87 72 88 struct nofork_save_area { 73 89 jmp_buf die_jmp; 90 void (*die_func)(void); 74 91 const char *applet_name; 75 92 uint32_t option_mask32; 76 int die_sleep;77 93 uint8_t xfunc_error_retval; 78 94 }; … … 80 96 { 81 97 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); 98 save->die_func = die_func; 82 99 save->applet_name = applet_name; 100 save->option_mask32 = option_mask32; 83 101 save->xfunc_error_retval = xfunc_error_retval; 84 save->option_mask32 = option_mask32;85 save->die_sleep = die_sleep;86 102 } 87 103 static void restore_nofork_data(struct nofork_save_area *save) 88 104 { 89 105 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); 106 die_func = save->die_func; 90 107 applet_name = save->applet_name; 108 option_mask32 = save->option_mask32; 91 109 xfunc_error_retval = save->xfunc_error_retval; 92 option_mask32 = save->option_mask32;93 die_sleep = save->die_sleep;94 110 } 95 111 … … 100 116 101 117 save_nofork_data(&old); 102 103 applet_name = APPLET_NAME(applet_no);104 118 105 119 xfunc_error_retval = EXIT_FAILURE; … … 134 148 argc++; 135 149 136 /* Special flag for xfunc_die(). If xfunc will "die" 137 * in NOFORK applet, xfunc_die() sees negative 138 * die_sleep and longjmp here instead. */ 139 die_sleep = -1; 140 150 /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ 151 die_func = jump; 141 152 rc = setjmp(die_jmp); 142 153 if (!rc) { … … 145 156 char *tmp_argv[argc+1]; 146 157 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); 158 applet_name = tmp_argv[0]; 147 159 /* Finally we can call NOFORK applet's main() */ 148 160 rc = applet_main[applet_no](argc, tmp_argv); 149 } else { /* xfunc died in NOFORK applet */ 150 /* in case they meant to return 0... */ 151 if (rc == -2222) 152 rc = 0; 161 } else { 162 /* xfunc died in NOFORK applet */ 153 163 } 154 164 -
branches/3.3/mindi-busybox/libbb/xatonum.c
r2725 r3621 69 69 return xatou_range(numstr, 0, 0xffff); 70 70 } 71 72 const struct suffix_mult bkm_suffixes[] = { 73 { "b", 512 }, 74 { "k", 1024 }, 75 { "m", 1024*1024 }, 76 { "", 0 } 77 }; 78 79 const struct suffix_mult cwbkMG_suffixes[] = { 80 { "c", 1 }, 81 { "w", 2 }, 82 { "b", 512 }, 83 { "kB", 1000 }, 84 { "kD", 1000 }, 85 { "k", 1024 }, 86 { "KB", 1000 }, /* compat with coreutils dd */ 87 { "KD", 1000 }, /* compat with coreutils dd */ 88 { "K", 1024 }, /* compat with coreutils dd */ 89 { "MB", 1000000 }, 90 { "MD", 1000000 }, 91 { "M", 1024*1024 }, 92 { "GB", 1000000000 }, 93 { "GD", 1000000000 }, 94 { "G", 1024*1024*1024 }, 95 /* "D" suffix for decimal is not in coreutils manpage, looks like it's deprecated */ 96 /* coreutils also understands TPEZY suffixes for tera- and so on, with B suffix for decimal */ 97 { "", 0 } 98 }; -
branches/3.3/mindi-busybox/libbb/xconnect.c
r3232 r3621 15 15 #include "libbb.h" 16 16 17 int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval) 18 { 19 return setsockopt(fd, level, optname, &optval, sizeof(int)); 20 } 21 int FAST_FUNC setsockopt_1(int fd, int level, int optname) 22 { 23 return setsockopt_int(fd, level, optname, 1); 24 } 25 int FAST_FUNC setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) 26 { 27 return setsockopt_int(fd, SOL_SOCKET, optname, optval); 28 } 29 int FAST_FUNC setsockopt_SOL_SOCKET_1(int fd, int optname) 30 { 31 return setsockopt_SOL_SOCKET_int(fd, optname, 1); 32 } 33 17 34 void FAST_FUNC setsockopt_reuseaddr(int fd) 18 35 { 19 setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1));36 setsockopt_SOL_SOCKET_1(fd, SO_REUSEADDR); 20 37 } 21 38 int FAST_FUNC setsockopt_broadcast(int fd) 22 39 { 23 return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); 40 return setsockopt_SOL_SOCKET_1(fd, SO_BROADCAST); 41 } 42 int FAST_FUNC setsockopt_keepalive(int fd) 43 { 44 return setsockopt_SOL_SOCKET_1(fd, SO_KEEPALIVE); 24 45 } 25 46 … … 172 193 struct addrinfo hint; 173 194 174 if (ENABLE_FEATURE_UNIX_LOCAL && strncmp(host, "local:", 6) == 0) {195 if (ENABLE_FEATURE_UNIX_LOCAL && is_prefixed_with(host, "local:")) { 175 196 struct sockaddr_un *sun; 176 197 -
branches/3.3/mindi-busybox/libbb/xfunc_die.c
r2725 r3621 8 8 */ 9 9 10 /* Keeping it separate allows to NOT suckin stdio for VERY small applets.10 /* Keeping it separate allows to NOT pull in stdio for VERY small applets. 11 11 * Try building busybox with only "true" enabled... */ 12 12 13 13 #include "libbb.h" 14 14 15 int die_sleep; 16 #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH 17 jmp_buf die_jmp; 18 #endif 15 void (*die_func)(void); 19 16 20 17 void FAST_FUNC xfunc_die(void) 21 18 { 22 if (die_sleep) { 23 if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) 24 && die_sleep < 0 25 ) { 26 /* Special case. We arrive here if NOFORK applet 27 * calls xfunc, which then decides to die. 28 * We don't die, but jump instead back to caller. 29 * NOFORK applets still cannot carelessly call xfuncs: 30 * p = xmalloc(10); 31 * q = xmalloc(10); // BUG! if this dies, we leak p! 32 */ 33 /* -2222 means "zero" (longjmp can't pass 0) 34 * run_nofork_applet() catches -2222. */ 35 longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); 36 } 37 sleep(die_sleep); 38 } 19 if (die_func) 20 die_func(); 39 21 exit(xfunc_error_retval); 40 22 } -
branches/3.3/mindi-busybox/libbb/xfuncs.c
r3232 r3621 26 26 27 27 /* Turn on nonblocking I/O on a fd */ 28 voidFAST_FUNC ndelay_on(int fd)28 int FAST_FUNC ndelay_on(int fd) 29 29 { 30 30 int flags = fcntl(fd, F_GETFL); 31 31 if (flags & O_NONBLOCK) 32 return ;32 return flags; 33 33 fcntl(fd, F_SETFL, flags | O_NONBLOCK); 34 } 35 36 void FAST_FUNC ndelay_off(int fd) 34 return flags; 35 } 36 37 int FAST_FUNC ndelay_off(int fd) 37 38 { 38 39 int flags = fcntl(fd, F_GETFL); 39 40 if (!(flags & O_NONBLOCK)) 40 return ;41 return flags; 41 42 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 43 return flags; 42 44 } 43 45 … … 206 208 207 209 // If we can't, it's smaller. 208 209 210 } else { 210 211 if (bottom == top) { … … 270 271 return err; 271 272 } 273 int FAST_FUNC get_terminal_width(int fd) 274 { 275 unsigned width; 276 get_terminal_width_height(fd, &width, NULL); 277 return width; 278 } 272 279 273 280 int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) … … 309 316 return 0; 310 317 } 318 319 // Useful when we do know that pid is valid, and we just want to wait 320 // for it to exit. Not existing pid is fatal. waitpid() status is not returned. 321 int FAST_FUNC wait_for_exitstatus(pid_t pid) 322 { 323 int exit_status, n; 324 325 n = safe_waitpid(pid, &exit_status, 0); 326 if (n < 0) 327 bb_perror_msg_and_die("waitpid"); 328 return exit_status; 329 } -
branches/3.3/mindi-busybox/libbb/xfuncs_printf.c
r3232 r3621 113 113 } 114 114 115 void* FAST_FUNC xmemdup(const void *s, int n) 116 { 117 return memcpy(xmalloc(n), s, n); 118 } 119 115 120 // Die if we can't open a file and return a FILE* to it. 116 121 // Notice we haven't got xfread(), This is for use with fscanf() and friends. … … 139 144 { 140 145 return xopen3(pathname, flags, 0666); 146 } 147 148 // Warn if we can't open a file and return a fd. 149 int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode) 150 { 151 int ret; 152 153 ret = open(pathname, flags, mode); 154 if (ret < 0) { 155 bb_perror_msg("can't open '%s'", pathname); 156 } 157 return ret; 158 } 159 160 // Warn if we can't open a file and return a fd. 161 int FAST_FUNC open_or_warn(const char *pathname, int flags) 162 { 163 return open3_or_warn(pathname, flags, 0666); 141 164 } 142 165 … … 150 173 } 151 174 152 // Warn if we can't open a file and return a fd. 153 int FAST_FUNC open3_or_warn(const char *pathname, int flags, int mode) 154 { 155 int ret; 156 157 ret = open(pathname, flags, mode); 158 if (ret < 0) { 159 bb_perror_msg("can't open '%s'", pathname); 160 } 161 return ret; 162 } 163 164 // Warn if we can't open a file and return a fd. 165 int FAST_FUNC open_or_warn(const char *pathname, int flags) 166 { 167 return open3_or_warn(pathname, flags, 0666); 175 int FAST_FUNC xopen_as_uid_gid(const char *pathname, int flags, uid_t u, gid_t g) 176 { 177 int fd; 178 uid_t old_euid = geteuid(); 179 gid_t old_egid = getegid(); 180 181 xsetegid(g); 182 xseteuid(u); 183 184 fd = xopen(pathname, flags); 185 186 xseteuid(old_euid); 187 xsetegid(old_egid); 188 189 return fd; 168 190 } 169 191 … … 352 374 } 353 375 376 void FAST_FUNC xsetegid(gid_t egid) 377 { 378 if (setegid(egid)) bb_perror_msg_and_die("setegid"); 379 } 380 381 void FAST_FUNC xseteuid(uid_t euid) 382 { 383 if (seteuid(euid)) bb_perror_msg_and_die("seteuid"); 384 } 385 354 386 // Die if we can't chdir to a new path. 355 387 void FAST_FUNC xchdir(const char *path) … … 357 389 if (chdir(path)) 358 390 bb_perror_msg_and_die("can't change directory to '%s'", path); 391 } 392 393 void FAST_FUNC xfchdir(int fd) 394 { 395 if (fchdir(fd)) 396 bb_perror_msg_and_die("fchdir"); 359 397 } 360 398 … … 542 580 char* FAST_FUNC xmalloc_ttyname(int fd) 543 581 { 544 char *buf = xzalloc(128); 545 int r = ttyname_r(fd, buf, 127); 546 if (r) { 547 free(buf); 548 buf = NULL; 549 } 550 return buf; 582 char buf[128]; 583 int r = ttyname_r(fd, buf, sizeof(buf) - 1); 584 if (r) 585 return NULL; 586 return xstrdup(buf); 551 587 } 552 588 … … 624 660 } 625 661 #endif 662 663 void FAST_FUNC xvfork_parent_waits_and_exits(void) 664 { 665 pid_t pid; 666 667 fflush_all(); 668 pid = xvfork(); 669 if (pid > 0) { 670 /* Parent */ 671 int exit_status = wait_for_exitstatus(pid); 672 if (WIFSIGNALED(exit_status)) 673 kill_myself_with_sig(WTERMSIG(exit_status)); 674 _exit(WEXITSTATUS(exit_status)); 675 } 676 /* Child continues */ 677 } -
branches/3.3/mindi-busybox/libbb/xreadlink.c
r2725 r3621 2 2 /* 3 3 * xreadlink.c - safe implementation of readlink. 4 * Returns a NULL on failure. ..4 * Returns a NULL on failure. 5 5 * 6 6 * Licensed under GPLv2, see file LICENSE in this source tree. … … 8 8 9 9 #include "libbb.h" 10 11 /* Some systems (eg Hurd) do not have MAXSYMLINKS definition, 12 * set it to some reasonable value if it isn't defined */ 13 #ifndef MAXSYMLINKS 14 # define MAXSYMLINKS 20 15 #endif 10 16 11 17 /* … … 103 109 char* FAST_FUNC xmalloc_realpath(const char *path) 104 110 { 105 #if defined(__GLIBC__) && !defined(__UCLIBC__) 111 /* NB: uclibc also defines __GLIBC__ 112 * Therefore the test "if glibc, or uclibc >= 0.9.31" looks a bit weird: 113 */ 114 #if defined(__GLIBC__) && \ 115 (!defined(__UCLIBC__) || UCLIBC_VERSION >= KERNEL_VERSION(0, 9, 31)) 106 116 /* glibc provides a non-standard extension */ 107 117 /* new: POSIX.1-2008 specifies this behavior as well */
Note:
See TracChangeset
for help on using the changeset viewer.