diff options
| author | Ron Yorston <rmy@pobox.com> | 2026-02-12 12:50:11 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2026-02-12 12:58:38 +0000 |
| commit | de7b34e8c779d8baca5abba1394284e0b6e87dc6 (patch) | |
| tree | 6cad7836abe5610f97c32d9b5d395f5e9c34929d | |
| parent | 7e0c303a8804608e3c11151655d270a63bfffcfa (diff) | |
| parent | 8424dc436a66a224b73429675a481d074fc2f8dc (diff) | |
| download | busybox-w32-merge.tar.gz busybox-w32-merge.tar.bz2 busybox-w32-merge.zip | |
Merge branch 'busybox' into mergemerge
34 files changed, 319 insertions, 238 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c index a6a8333a8..a53da8df1 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
| @@ -1694,7 +1694,7 @@ static void unpack_package(deb_file_t *deb_file) | |||
| 1694 | accept_list = NULL; | 1694 | accept_list = NULL; |
| 1695 | i = 0; | 1695 | i = 0; |
| 1696 | while (i < ARRAY_SIZE(all_control_files)) { | 1696 | while (i < ARRAY_SIZE(all_control_files)) { |
| 1697 | char *c = xasprintf("./%s", all_control_files[i]); | 1697 | char *c = concat_path_file(".", all_control_files[i]); |
| 1698 | llist_add_to(&accept_list, c); | 1698 | llist_add_to(&accept_list, c); |
| 1699 | i++; | 1699 | i++; |
| 1700 | } | 1700 | } |
diff --git a/archival/libarchive/lzo1x_9x.c b/archival/libarchive/lzo1x_9x.c index df26b375f..2c405b636 100644 --- a/archival/libarchive/lzo1x_9x.c +++ b/archival/libarchive/lzo1x_9x.c | |||
| @@ -797,7 +797,6 @@ static int lzo1x_999_compress_internal(const uint8_t *in, unsigned in_len, | |||
| 797 | if (swd->use_best_off) | 797 | if (swd->use_best_off) |
| 798 | better_match(swd, &m_len, &m_off); | 798 | better_match(swd, &m_len, &m_off); |
| 799 | #endif | 799 | #endif |
| 800 | |||
| 801 | /* shall we try a lazy match ? */ | 800 | /* shall we try a lazy match ? */ |
| 802 | ahead = 0; | 801 | ahead = 0; |
| 803 | if (m_len >= max_lazy) { | 802 | if (m_len >= max_lazy) { |
| @@ -811,7 +810,6 @@ static int lzo1x_999_compress_internal(const uint8_t *in, unsigned in_len, | |||
| 811 | max_ahead = LZO_MIN(2, (unsigned)l1 - 1); | 810 | max_ahead = LZO_MIN(2, (unsigned)l1 - 1); |
| 812 | } | 811 | } |
| 813 | 812 | ||
| 814 | |||
| 815 | while (ahead < max_ahead && c->look > m_len) { | 813 | while (ahead < max_ahead && c->look > m_len) { |
| 816 | int lazy_match_min_gain; | 814 | int lazy_match_min_gain; |
| 817 | 815 | ||
diff --git a/archival/lzop.c b/archival/lzop.c index bdcc6d548..98587e8dd 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
| @@ -208,7 +208,6 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, | |||
| 208 | lit = 0; | 208 | lit = 0; |
| 209 | goto match_done; | 209 | goto match_done; |
| 210 | 210 | ||
| 211 | |||
| 212 | /* handle matches */ | 211 | /* handle matches */ |
| 213 | do { | 212 | do { |
| 214 | if (t < 16) { /* a M1 match */ | 213 | if (t < 16) { /* a M1 match */ |
diff --git a/coreutils/factor.c b/coreutils/factor.c index 9de5ea8eb..1889836b0 100644 --- a/coreutils/factor.c +++ b/coreutils/factor.c | |||
| @@ -136,7 +136,7 @@ static void factorize(wide_t N); | |||
| 136 | 136 | ||
| 137 | static half_t isqrt_odd(wide_t N) | 137 | static half_t isqrt_odd(wide_t N) |
| 138 | { | 138 | { |
| 139 | half_t s = isqrt(N); | 139 | half_t s = isqrt_ull(N); |
| 140 | /* s^2 is <= N, (s+1)^2 > N */ | 140 | /* s^2 is <= N, (s+1)^2 > N */ |
| 141 | 141 | ||
| 142 | /* If s^2 in fact is EQUAL to N, it's very lucky. | 142 | /* If s^2 in fact is EQUAL to N, it's very lucky. |
diff --git a/editors/sed.c b/editors/sed.c index 204417108..b9e2c40ad 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
| @@ -668,9 +668,8 @@ static void add_cmd(const char *cmdstr) | |||
| 668 | 668 | ||
| 669 | /* Append this line to any unfinished line from last time. */ | 669 | /* Append this line to any unfinished line from last time. */ |
| 670 | if (G.add_cmd_line) { | 670 | if (G.add_cmd_line) { |
| 671 | char *tp = xasprintf("%s\n%s", G.add_cmd_line, cmdstr); | 671 | cmdstr = xasprintf_inplace(G.add_cmd_line, |
| 672 | free(G.add_cmd_line); | 672 | "%s\n%s", G.add_cmd_line, cmdstr); |
| 673 | cmdstr = G.add_cmd_line = tp; | ||
| 674 | } | 673 | } |
| 675 | 674 | ||
| 676 | /* If this line ends with unescaped backslash, request next line. */ | 675 | /* If this line ends with unescaped backslash, request next line. */ |
diff --git a/editors/vi.c b/editors/vi.c index 7ec3427f9..e3ad120f6 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
| @@ -612,7 +612,6 @@ static int crashme = 0; | |||
| 612 | #endif | 612 | #endif |
| 613 | 613 | ||
| 614 | static void show_status_line(void); // put a message on the bottom line | 614 | static void show_status_line(void); // put a message on the bottom line |
| 615 | static void status_line_bold(const char *, ...); | ||
| 616 | 615 | ||
| 617 | static void show_help(void) | 616 | static void show_help(void) |
| 618 | { | 617 | { |
| @@ -1172,11 +1171,15 @@ static void redraw(int full_screen) | |||
| 1172 | //----- Flash the screen -------------------------------------- | 1171 | //----- Flash the screen -------------------------------------- |
| 1173 | static void flash(int h) | 1172 | static void flash(int h) |
| 1174 | { | 1173 | { |
| 1175 | standout_start(); | 1174 | //standout_start(); |
| 1176 | redraw(TRUE); | 1175 | //redraw(TRUE); |
| 1176 | write1(ESC"[?5h"); // "reverse screen on" | ||
| 1177 | |||
| 1177 | mysleep(h); | 1178 | mysleep(h); |
| 1178 | standout_end(); | 1179 | |
| 1179 | redraw(TRUE); | 1180 | //standout_end(); |
| 1181 | //redraw(TRUE); | ||
| 1182 | write1(ESC"[?5l"); // "reverse screen off" | ||
| 1180 | } | 1183 | } |
| 1181 | 1184 | ||
| 1182 | static void indicate_error(void) | 1185 | static void indicate_error(void) |
| @@ -1411,11 +1414,10 @@ static void show_status_line(void) | |||
| 1411 | go_bottom_and_clear_to_eol(); | 1414 | go_bottom_and_clear_to_eol(); |
| 1412 | write1(status_buffer); | 1415 | write1(status_buffer); |
| 1413 | if (have_status_msg) { | 1416 | if (have_status_msg) { |
| 1414 | if (((int)strlen(status_buffer) - (have_status_msg - 1)) > | 1417 | int n = (int)strlen(status_buffer) - (have_status_msg - 1); |
| 1415 | (columns - 1) ) { | 1418 | // careful with int->unsigned promotion in comparison! |
| 1416 | have_status_msg = 0; | 1419 | if (n >= 0 && n >= columns) |
| 1417 | Hit_Return(); | 1420 | Hit_Return(); |
| 1418 | } | ||
| 1419 | have_status_msg = 0; | 1421 | have_status_msg = 0; |
| 1420 | } | 1422 | } |
| 1421 | place_cursor(crow, ccol); // put cursor back in correct place | 1423 | place_cursor(crow, ccol); // put cursor back in correct place |
| @@ -2725,7 +2727,7 @@ static char *get_one_address(char *p, int *result, int *valid) | |||
| 2725 | 2727 | ||
| 2726 | // Read line addresses for a colon command. The user can enter as | 2728 | // Read line addresses for a colon command. The user can enter as |
| 2727 | // many as they like but only the last two will be used. | 2729 | // many as they like but only the last two will be used. |
| 2728 | static char *get_address(char *p, int *b, int *e, unsigned int *got) | 2730 | static char *get_address(char *p, int *b, int *e, unsigned *got) |
| 2729 | { | 2731 | { |
| 2730 | int state = GET_ADDRESS; | 2732 | int state = GET_ADDRESS; |
| 2731 | int valid; | 2733 | int valid; |
| @@ -2839,19 +2841,23 @@ static void setops(char *args, int flg_no) | |||
| 2839 | # if ENABLE_FEATURE_VI_COLON_EXPAND | 2841 | # if ENABLE_FEATURE_VI_COLON_EXPAND |
| 2840 | static char *expand_args(char *args) | 2842 | static char *expand_args(char *args) |
| 2841 | { | 2843 | { |
| 2842 | char *s, *t; | 2844 | char *s; |
| 2843 | const char *replace; | 2845 | const char *replace; |
| 2844 | 2846 | ||
| 2845 | args = xstrdup(args); | 2847 | args = xstrdup(args); |
| 2846 | for (s = args; *s; s++) { | 2848 | for (s = args; *s; s++) { |
| 2849 | unsigned n; | ||
| 2850 | |||
| 2847 | if (*s == '%') { | 2851 | if (*s == '%') { |
| 2848 | replace = current_filename; | 2852 | replace = current_filename; |
| 2849 | } else if (*s == '#') { | 2853 | } else if (*s == '#') { |
| 2850 | replace = alt_filename; | 2854 | replace = alt_filename; |
| 2851 | } else { | 2855 | } else { |
| 2852 | if (*s == '\\' && s[1] != '\0') { | 2856 | if (*s == '\\' && s[1] != '\0') { |
| 2853 | for (t = s++; *t; t++) | 2857 | char *t; |
| 2858 | for (t = s; *t; t++) | ||
| 2854 | *t = t[1]; | 2859 | *t = t[1]; |
| 2860 | s++; | ||
| 2855 | } | 2861 | } |
| 2856 | continue; | 2862 | continue; |
| 2857 | } | 2863 | } |
| @@ -2862,11 +2868,9 @@ static char *expand_args(char *args) | |||
| 2862 | return NULL; | 2868 | return NULL; |
| 2863 | } | 2869 | } |
| 2864 | 2870 | ||
| 2865 | *s = '\0'; | 2871 | n = (s - args); |
| 2866 | t = xasprintf("%s%s%s", args, replace, s+1); | 2872 | xasprintf_inplace(args, "%.*s%s%s", n, args, replace, s+1); |
| 2867 | s = t + (s - args) + strlen(replace); | 2873 | s = args + n + strlen(replace); |
| 2868 | free(args); | ||
| 2869 | args = t; | ||
| 2870 | } | 2874 | } |
| 2871 | return args; | 2875 | return args; |
| 2872 | } | 2876 | } |
| @@ -2944,7 +2948,6 @@ static char *regex_search(char *q, regex_t *preg, const char *Rorig, | |||
| 2944 | # define strchr_backslash(s, c) strchr(s, c) | 2948 | # define strchr_backslash(s, c) strchr(s, c) |
| 2945 | #endif /* ENABLE_FEATURE_VI_REGEX_SEARCH */ | 2949 | #endif /* ENABLE_FEATURE_VI_REGEX_SEARCH */ |
| 2946 | 2950 | ||
| 2947 | // buf must be no longer than MAX_INPUT_LEN! | ||
| 2948 | static void colon(char *buf) | 2951 | static void colon(char *buf) |
| 2949 | { | 2952 | { |
| 2950 | #if !ENABLE_FEATURE_VI_COLON | 2953 | #if !ENABLE_FEATURE_VI_COLON |
| @@ -3004,16 +3007,17 @@ static void colon(char *buf) | |||
| 3004 | } | 3007 | } |
| 3005 | not_implemented(p); | 3008 | not_implemented(p); |
| 3006 | #else | 3009 | #else |
| 3007 | 3010 | char cmd[sizeof("features!")]; // longest known command + NUL | |
| 3011 | char *args; | ||
| 3012 | int cmdlen; | ||
| 3013 | char *useforce; | ||
| 3014 | char *q, *r; | ||
| 3015 | int b, e; | ||
| 3008 | // check how many addresses we got | 3016 | // check how many addresses we got |
| 3009 | # define GOT_ADDRESS (got & 1) | 3017 | # define GOT_ADDRESS (got & 1) |
| 3010 | # define GOT_RANGE ((got & 3) == 3) | 3018 | # define GOT_RANGE ((got & 3) == 3) |
| 3011 | 3019 | unsigned got; | |
| 3012 | char c, *buf1, *q, *r; | 3020 | char *exp = NULL; // may hold expand_args() result: if VI_COLON_EXPAND, needs freeing! |
| 3013 | char *fn, cmd[MAX_INPUT_LEN], *cmdend, *args, *exp = NULL; | ||
| 3014 | int i, l, li, b, e; | ||
| 3015 | unsigned int got; | ||
| 3016 | int useforce; | ||
| 3017 | 3021 | ||
| 3018 | // :3154 // if (-e line 3154) goto it else stay put | 3022 | // :3154 // if (-e line 3154) goto it else stay put |
| 3019 | // :4,33w! foo // write a portion of buffer to file "foo" | 3023 | // :4,33w! foo // write a portion of buffer to file "foo" |
| @@ -3028,52 +3032,38 @@ static void colon(char *buf) | |||
| 3028 | // :/xyz/ // goto the "xyz" line | 3032 | // :/xyz/ // goto the "xyz" line |
| 3029 | // :s/find/replace/ // substitute pattern "find" with "replace" | 3033 | // :s/find/replace/ // substitute pattern "find" with "replace" |
| 3030 | // :!<cmd> // run <cmd> then return | 3034 | // :!<cmd> // run <cmd> then return |
| 3031 | // | ||
| 3032 | 3035 | ||
| 3033 | while (*buf == ':') | 3036 | while (*buf == ':') |
| 3034 | buf++; // move past leading colons | 3037 | buf++; // move past leading colons |
| 3035 | while (isblank(*buf)) | 3038 | buf = skip_whitespace(buf); // move past leading blanks |
| 3036 | buf++; // move past leading blanks | 3039 | if (!*buf || *buf == '"') |
| 3037 | if (!buf[0] || buf[0] == '"') | ||
| 3038 | goto ret; // ignore empty lines or those starting with '"' | 3040 | goto ret; // ignore empty lines or those starting with '"' |
| 3039 | 3041 | ||
| 3040 | li = i = 0; | 3042 | // look for optional address(es) ":." ":1" ":1,9" ":'q,'a" ":%" |
| 3041 | b = e = -1; | 3043 | b = e = -1; |
| 3042 | got = 0; | 3044 | got = 0; |
| 3043 | li = count_lines(text, end - 1); | ||
| 3044 | fn = current_filename; | ||
| 3045 | |||
| 3046 | // look for optional address(es) :. :1 :1,9 :'q,'a :% | ||
| 3047 | buf = get_address(buf, &b, &e, &got); | 3045 | buf = get_address(buf, &b, &e, &got); |
| 3048 | if (buf == NULL) { | 3046 | if (buf == NULL) |
| 3049 | goto ret; | 3047 | goto ret; |
| 3050 | } | ||
| 3051 | 3048 | ||
| 3052 | // get the COMMAND into cmd[] | 3049 | // get the COMMAND into cmd[] |
| 3053 | strcpy(cmd, buf); | 3050 | safe_strncpy(cmd, buf, sizeof(cmd)); |
| 3054 | buf1 = cmd; | 3051 | skip_non_whitespace(cmd)[0] = '\0'; |
| 3055 | while (!isspace(*buf1) && *buf1 != '\0') { | 3052 | useforce = last_char_is(cmd, '!'); |
| 3056 | buf1++; | 3053 | if (useforce && useforce > cmd) |
| 3057 | } | 3054 | *useforce = '\0'; // "CMD!" -> "CMD" (unless single "!") |
| 3058 | cmdend = buf1; | 3055 | // find ARGuments |
| 3059 | // get any ARGuments | 3056 | args = skip_whitespace(skip_non_whitespace(buf)); |
| 3060 | while (isblank(*buf1)) | 3057 | |
| 3061 | buf1++; | ||
| 3062 | args = buf1; | ||
| 3063 | *cmdend = '\0'; | ||
| 3064 | useforce = FALSE; | ||
| 3065 | if (cmdend > cmd && cmdend[-1] == '!') { | ||
| 3066 | useforce = TRUE; | ||
| 3067 | cmdend[-1] = '\0'; // get rid of ! | ||
| 3068 | } | ||
| 3069 | // assume the command will want a range, certain commands | 3058 | // assume the command will want a range, certain commands |
| 3070 | // (read, substitute) need to adjust these assumptions | 3059 | // (read, substitute) need to adjust these assumptions |
| 3071 | if (!GOT_ADDRESS) { | 3060 | q = text; // if no addr, use 1,$ for the range |
| 3072 | q = text; // no addr, use 1,$ for the range | 3061 | r = end - 1; |
| 3073 | r = end - 1; | 3062 | if (GOT_ADDRESS) { // at least one addr was given, get its details |
| 3074 | } else { | 3063 | int lines; |
| 3075 | // at least one addr was given, get its details | 3064 | if (e < 0 |
| 3076 | if (e < 0 || e > li) { | 3065 | || e > (lines = count_lines(text, end - 1)) |
| 3066 | ) { | ||
| 3077 | status_line_bold("Invalid range"); | 3067 | status_line_bold("Invalid range"); |
| 3078 | goto ret; | 3068 | goto ret; |
| 3079 | } | 3069 | } |
| @@ -3083,31 +3073,28 @@ static void colon(char *buf) | |||
| 3083 | // number of the single line the user wants. | 3073 | // number of the single line the user wants. |
| 3084 | // Reset the end pointer to the end of that line. | 3074 | // Reset the end pointer to the end of that line. |
| 3085 | r = end_line(q); | 3075 | r = end_line(q); |
| 3086 | li = 1; | ||
| 3087 | } else { | 3076 | } else { |
| 3088 | // we were given two addrs. change the | 3077 | // we were given two addrs. change the |
| 3089 | // start pointer to the addr given by user. | 3078 | // start pointer to the addr given by user. |
| 3090 | if (b < 0 || b > li || b > e) { | 3079 | if (b < 0 || b > lines || b > e) { |
| 3091 | status_line_bold("Invalid range"); | 3080 | status_line_bold("Invalid range"); |
| 3092 | goto ret; | 3081 | goto ret; |
| 3093 | } | 3082 | } |
| 3094 | q = find_line(b); // what line is #b | 3083 | q = find_line(b); // what line is #b |
| 3095 | r = end_line(r); | 3084 | r = end_line(r); |
| 3096 | li = e - b + 1; | ||
| 3097 | } | 3085 | } |
| 3098 | } | 3086 | } |
| 3099 | // ------------ now look for the command ------------ | 3087 | // ------------ now look for the command ------------ |
| 3100 | i = strlen(cmd); | 3088 | cmdlen = strlen(cmd); |
| 3101 | if (i == 0) { // :123CR goto line #123 | 3089 | if (cmdlen == 0) { // ":123<enter>" - goto line #123 |
| 3102 | if (e >= 0) { | 3090 | if (e >= 0) { |
| 3103 | dot = find_line(e); // what line is #e | 3091 | dot = find_line(e); // what line is #e |
| 3104 | dot_skip_over_ws(); | 3092 | dot_skip_over_ws(); |
| 3105 | } | 3093 | } |
| 3106 | } | 3094 | } |
| 3107 | # if ENABLE_FEATURE_ALLOW_EXEC | 3095 | # if ENABLE_FEATURE_ALLOW_EXEC |
| 3108 | else if (cmd[0] == '!') { // run a cmd | 3096 | else if (cmd[0] == '!') { // ":!CMD" - run shell CMD |
| 3109 | int retcode; | 3097 | int retcode; |
| 3110 | // :!ls run the <cmd> | ||
| 3111 | if (GOT_ADDRESS) { | 3098 | if (GOT_ADDRESS) { |
| 3112 | status_line_bold("Range not allowed"); | 3099 | status_line_bold("Range not allowed"); |
| 3113 | goto ret; | 3100 | goto ret; |
| @@ -3129,25 +3116,27 @@ static void colon(char *buf) | |||
| 3129 | e = count_lines(text, dot); | 3116 | e = count_lines(text, dot); |
| 3130 | } | 3117 | } |
| 3131 | status_line("%d", e); | 3118 | status_line("%d", e); |
| 3132 | } else if (strncmp(cmd, "delete", i) == 0) { // delete lines | 3119 | } else if (strncmp(cmd, "delete", cmdlen) == 0) { // delete lines |
| 3133 | if (!GOT_ADDRESS) { // no addr given- use defaults | 3120 | if (!GOT_ADDRESS) { // no addr given- use defaults |
| 3134 | q = begin_line(dot); // assume .,. for the range | 3121 | q = begin_line(dot); // assume .,. for the range |
| 3135 | r = end_line(dot); | 3122 | r = end_line(dot); |
| 3136 | } | 3123 | } |
| 3137 | dot = yank_delete(q, r, WHOLE, YANKDEL, ALLOW_UNDO); // save, then delete lines | 3124 | dot = yank_delete(q, r, WHOLE, YANKDEL, ALLOW_UNDO); // save, then delete lines |
| 3138 | dot_skip_over_ws(); | 3125 | dot_skip_over_ws(); |
| 3139 | } else if (strncmp(cmd, "edit", i) == 0) { // Edit a file | 3126 | } else if (strncmp(cmd, "edit", cmdlen) == 0) { // Edit a file |
| 3140 | int size; | 3127 | int size; |
| 3128 | char *fn; | ||
| 3141 | 3129 | ||
| 3142 | // don't edit, if the current file has been modified | 3130 | // don't edit, if the current file has been modified |
| 3143 | if (modified_count && !useforce) { | 3131 | if (modified_count && !useforce) { |
| 3144 | status_line_bold("No write since last change (:%s! overrides)", cmd); | 3132 | status_line_bold("No write since last change (:%s! overrides)", cmd); |
| 3145 | goto ret; | 3133 | goto ret; |
| 3146 | } | 3134 | } |
| 3135 | fn = current_filename; | ||
| 3147 | if (args[0]) { | 3136 | if (args[0]) { |
| 3148 | // the user supplied a file name | 3137 | // the user supplied a file name |
| 3149 | fn = exp = expand_args(args); | 3138 | fn = expand_args(args); |
| 3150 | if (exp == NULL) | 3139 | if (fn == NULL) |
| 3151 | goto ret; | 3140 | goto ret; |
| 3152 | } else if (current_filename == NULL) { | 3141 | } else if (current_filename == NULL) { |
| 3153 | // no user file name, no current name- punt | 3142 | // no user file name, no current name- punt |
| @@ -3167,8 +3156,6 @@ static void colon(char *buf) | |||
| 3167 | reg[YDreg] = NULL; | 3156 | reg[YDreg] = NULL; |
| 3168 | } | 3157 | } |
| 3169 | # endif | 3158 | # endif |
| 3170 | // how many lines in text[]? | ||
| 3171 | li = count_lines(text, end - 1); | ||
| 3172 | status_line("'%s'%s" | 3159 | status_line("'%s'%s" |
| 3173 | IF_FEATURE_VI_READONLY("%s") | 3160 | IF_FEATURE_VI_READONLY("%s") |
| 3174 | " %uL, %uC", | 3161 | " %uL, %uC", |
| @@ -3177,9 +3164,10 @@ static void colon(char *buf) | |||
| 3177 | IF_FEATURE_VI_READONLY( | 3164 | IF_FEATURE_VI_READONLY( |
| 3178 | ((readonly_mode) ? " [Readonly]" : ""), | 3165 | ((readonly_mode) ? " [Readonly]" : ""), |
| 3179 | ) | 3166 | ) |
| 3180 | li, (int)(end - text) | 3167 | count_lines(text, end - 1), |
| 3168 | (int)(end - text) | ||
| 3181 | ); | 3169 | ); |
| 3182 | } else if (strncmp(cmd, "file", i) == 0) { // what File is this | 3170 | } else if (strncmp(cmd, "file", cmdlen) == 0) { // what File is this |
| 3183 | if (e >= 0) { | 3171 | if (e >= 0) { |
| 3184 | status_line_bold("No address allowed on this command"); | 3172 | status_line_bold("No address allowed on this command"); |
| 3185 | goto ret; | 3173 | goto ret; |
| @@ -3194,46 +3182,52 @@ static void colon(char *buf) | |||
| 3194 | // user wants file status info | 3182 | // user wants file status info |
| 3195 | last_status_cksum = 0; // force status update | 3183 | last_status_cksum = 0; // force status update |
| 3196 | } | 3184 | } |
| 3197 | } else if (strncmp(cmd, "features", i) == 0) { // what features are available | 3185 | } else if (strncmp(cmd, "features", cmdlen) == 0) { // what features are available |
| 3198 | // print out values of all features | 3186 | // print out values of all features |
| 3199 | go_bottom_and_clear_to_eol(); | 3187 | go_bottom_and_clear_to_eol(); |
| 3200 | cookmode(); | 3188 | cookmode(); |
| 3201 | show_help(); | 3189 | show_help(); |
| 3202 | rawmode(); | 3190 | rawmode(); |
| 3203 | Hit_Return(); | 3191 | Hit_Return(); |
| 3204 | } else if (strncmp(cmd, "list", i) == 0) { // literal print line | 3192 | } else if (strncmp(cmd, "list", cmdlen) == 0) { // literal print line |
| 3193 | char *dst; | ||
| 3205 | if (!GOT_ADDRESS) { // no addr given- use defaults | 3194 | if (!GOT_ADDRESS) { // no addr given- use defaults |
| 3206 | q = begin_line(dot); // assume .,. for the range | 3195 | q = begin_line(dot); // assume .,. for the range |
| 3207 | r = end_line(dot); | 3196 | r = end_line(dot); |
| 3208 | } | 3197 | } |
| 3209 | go_bottom_and_clear_to_eol(); | 3198 | have_status_msg = 1; |
| 3210 | puts("\r"); | 3199 | dst = status_buffer; |
| 3211 | for (; q <= r; q++) { | 3200 | #define MAXPRINT (sizeof(ESC_BOLD_TEXT "^?" ESC_NORM_TEXT) + 1) |
| 3201 | while (q <= r && dst < status_buffer + STATUS_BUFFER_LEN - MAXPRINT) { | ||
| 3202 | char c; | ||
| 3212 | int c_is_no_print; | 3203 | int c_is_no_print; |
| 3213 | 3204 | ||
| 3214 | c = *q; | 3205 | c = *q++; |
| 3206 | if (c == '\n') { | ||
| 3207 | *dst++ = '$'; | ||
| 3208 | break; | ||
| 3209 | } | ||
| 3215 | c_is_no_print = (c & 0x80) && !Isprint(c); | 3210 | c_is_no_print = (c & 0x80) && !Isprint(c); |
| 3216 | if (c_is_no_print) { | 3211 | if (c_is_no_print) { |
| 3217 | c = '.'; | 3212 | //TODO: print fewer ESC if more than one ctrl char |
| 3218 | standout_start(); | 3213 | dst = stpcpy(dst, ESC_BOLD_TEXT); |
| 3214 | *dst++ = '.'; | ||
| 3215 | dst = stpcpy(dst, ESC_NORM_TEXT); | ||
| 3216 | continue; | ||
| 3219 | } | 3217 | } |
| 3220 | if (c == '\n') { | 3218 | if (c < ' ' || c == 127) { |
| 3221 | write1("$\r"); | 3219 | *dst++ = '^'; |
| 3222 | } else if (c < ' ' || c == 127) { | ||
| 3223 | bb_putchar('^'); | ||
| 3224 | if (c == 127) | 3220 | if (c == 127) |
| 3225 | c = '?'; | 3221 | c = '?'; |
| 3226 | else | 3222 | else |
| 3227 | c += '@'; | 3223 | c += '@'; |
| 3228 | } | 3224 | } |
| 3229 | bb_putchar(c); | 3225 | *dst++ = c; |
| 3230 | if (c_is_no_print) | ||
| 3231 | standout_end(); | ||
| 3232 | } | 3226 | } |
| 3233 | Hit_Return(); | 3227 | *dst = '\0'; |
| 3234 | } else if (strncmp(cmd, "quit", i) == 0 // quit | 3228 | } else if (strncmp(cmd, "quit", cmdlen) == 0 // quit |
| 3235 | || strncmp(cmd, "next", i) == 0 // edit next file | 3229 | || strncmp(cmd, "next", cmdlen) == 0 // edit next file |
| 3236 | || strncmp(cmd, "prev", i) == 0 // edit previous file | 3230 | || strncmp(cmd, "prev", cmdlen) == 0 // edit previous file |
| 3237 | ) { | 3231 | ) { |
| 3238 | int n; | 3232 | int n; |
| 3239 | if (useforce) { | 3233 | if (useforce) { |
| @@ -3268,13 +3262,14 @@ static void colon(char *buf) | |||
| 3268 | optind -= 2; | 3262 | optind -= 2; |
| 3269 | } | 3263 | } |
| 3270 | editing = 0; | 3264 | editing = 0; |
| 3271 | } else if (strncmp(cmd, "read", i) == 0) { // read file into text[] | 3265 | } else if (strncmp(cmd, "read", cmdlen) == 0) { // read file into text[] |
| 3272 | int size, num; | 3266 | int size, num; |
| 3267 | char *fn = current_filename; | ||
| 3273 | 3268 | ||
| 3274 | if (args[0]) { | 3269 | if (args[0]) { |
| 3275 | // the user supplied a file name | 3270 | // the user supplied a file name |
| 3276 | fn = exp = expand_args(args); | 3271 | fn = expand_args(args); |
| 3277 | if (exp == NULL) | 3272 | if (fn == NULL) |
| 3278 | goto ret; | 3273 | goto ret; |
| 3279 | init_filename(fn); | 3274 | init_filename(fn); |
| 3280 | } else if (current_filename == NULL) { | 3275 | } else if (current_filename == NULL) { |
| @@ -3300,17 +3295,16 @@ static void colon(char *buf) | |||
| 3300 | } | 3295 | } |
| 3301 | if (size < 0) | 3296 | if (size < 0) |
| 3302 | goto ret; // nothing was inserted | 3297 | goto ret; // nothing was inserted |
| 3303 | // how many lines in text[]? | ||
| 3304 | li = count_lines(q, q + size - 1); | ||
| 3305 | status_line("'%s'" | 3298 | status_line("'%s'" |
| 3306 | IF_FEATURE_VI_READONLY("%s") | 3299 | IF_FEATURE_VI_READONLY("%s") |
| 3307 | " %uL, %uC", | 3300 | " %uL, %uC", |
| 3308 | fn, | 3301 | fn, |
| 3309 | IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),) | 3302 | IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),) |
| 3310 | li, size | 3303 | count_lines(q, q + size - 1), |
| 3304 | size | ||
| 3311 | ); | 3305 | ); |
| 3312 | dot = find_line(num); | 3306 | dot = find_line(num); |
| 3313 | } else if (strncmp(cmd, "rewind", i) == 0) { // rewind cmd line args | 3307 | } else if (strncmp(cmd, "rewind", cmdlen) == 0) { // rewind cmd line args |
| 3314 | if (modified_count && !useforce) { | 3308 | if (modified_count && !useforce) { |
| 3315 | status_line_bold("No write since last change (:%s! overrides)", cmd); | 3309 | status_line_bold("No write since last change (:%s! overrides)", cmd); |
| 3316 | } else { | 3310 | } else { |
| @@ -3319,11 +3313,12 @@ static void colon(char *buf) | |||
| 3319 | editing = 0; | 3313 | editing = 0; |
| 3320 | } | 3314 | } |
| 3321 | # if ENABLE_FEATURE_VI_SET | 3315 | # if ENABLE_FEATURE_VI_SET |
| 3322 | } else if (strncmp(cmd, "set", i) == 0) { // set or clear features | 3316 | } else if (strncmp(cmd, "set", cmdlen) == 0 // set or clear features |
| 3317 | IF_FEATURE_VI_SEARCH(&& cmdlen > 1) // (do not confuse with "s /find/repl/") | ||
| 3318 | ) { | ||
| 3323 | # if ENABLE_FEATURE_VI_SETOPTS | 3319 | # if ENABLE_FEATURE_VI_SETOPTS |
| 3324 | char *argp, *argn, oldch; | 3320 | char *argp, *argn, oldch; |
| 3325 | # endif | 3321 | # endif |
| 3326 | // only blank is regarded as args delimiter. What about tab '\t'? | ||
| 3327 | if (!args[0] || strcmp(args, "all") == 0) { | 3322 | if (!args[0] || strcmp(args, "all") == 0) { |
| 3328 | // print out values of all options | 3323 | // print out values of all options |
| 3329 | # if ENABLE_FEATURE_VI_SETOPTS | 3324 | # if ENABLE_FEATURE_VI_SETOPTS |
| @@ -3370,7 +3365,7 @@ static void colon(char *buf) | |||
| 3370 | # if ENABLE_FEATURE_VI_SETOPTS | 3365 | # if ENABLE_FEATURE_VI_SETOPTS |
| 3371 | argp = args; | 3366 | argp = args; |
| 3372 | while (*argp) { | 3367 | while (*argp) { |
| 3373 | i = 0; | 3368 | int i = 0; |
| 3374 | if (argp[0] == 'n' && argp[1] == 'o') // "noXXX" | 3369 | if (argp[0] == 'n' && argp[1] == 'o') // "noXXX" |
| 3375 | i = 2; | 3370 | i = 2; |
| 3376 | argn = skip_non_whitespace(argp); | 3371 | argn = skip_non_whitespace(argp); |
| @@ -3385,8 +3380,10 @@ static void colon(char *buf) | |||
| 3385 | 3380 | ||
| 3386 | # if ENABLE_FEATURE_VI_SEARCH | 3381 | # if ENABLE_FEATURE_VI_SEARCH |
| 3387 | } else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern | 3382 | } else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern |
| 3383 | char c; | ||
| 3388 | char *F, *R, *flags; | 3384 | char *F, *R, *flags; |
| 3389 | size_t len_F, len_R; | 3385 | size_t len_F, len_R; |
| 3386 | int i; | ||
| 3390 | int gflag = 0; // global replace flag | 3387 | int gflag = 0; // global replace flag |
| 3391 | int subs = 0; // number of substitutions | 3388 | int subs = 0; // number of substitutions |
| 3392 | # if ENABLE_FEATURE_VI_VERBOSE_STATUS | 3389 | # if ENABLE_FEATURE_VI_VERBOSE_STATUS |
| @@ -3400,12 +3397,12 @@ static void colon(char *buf) | |||
| 3400 | int undo = 0; | 3397 | int undo = 0; |
| 3401 | # endif | 3398 | # endif |
| 3402 | # endif | 3399 | # endif |
| 3403 | 3400 | buf = skip_whitespace(buf + 1); // spaces allowed: "s /find/repl/" | |
| 3404 | // F points to the "find" pattern | 3401 | // F points to the "find" pattern |
| 3405 | // R points to the "replace" pattern | 3402 | // R points to the "replace" pattern |
| 3406 | // replace the cmd line delimiters "/" with NULs | 3403 | // replace the cmd line delimiters "/" with NULs |
| 3407 | c = buf[1]; // what is the delimiter | 3404 | c = buf[0]; // what is the delimiter |
| 3408 | F = buf + 2; // start of "find" | 3405 | F = buf + 1; // start of "find" |
| 3409 | R = strchr_backslash(F, c); // middle delimiter | 3406 | R = strchr_backslash(F, c); // middle delimiter |
| 3410 | if (!R) | 3407 | if (!R) |
| 3411 | goto colon_s_fail; | 3408 | goto colon_s_fail; |
| @@ -3450,7 +3447,6 @@ static void colon(char *buf) | |||
| 3450 | # else | 3447 | # else |
| 3451 | len_R = strlen(R); | 3448 | len_R = strlen(R); |
| 3452 | # endif | 3449 | # endif |
| 3453 | |||
| 3454 | for (i = b; i <= e; i++) { // so, :20,23 s \0 find \0 replace \0 | 3450 | for (i = b; i <= e; i++) { // so, :20,23 s \0 find \0 replace \0 |
| 3455 | char *ls = q; // orig line start | 3451 | char *ls = q; // orig line start |
| 3456 | char *found; | 3452 | char *found; |
| @@ -3522,15 +3518,16 @@ static void colon(char *buf) | |||
| 3522 | regfree(&preg); | 3518 | regfree(&preg); |
| 3523 | # endif | 3519 | # endif |
| 3524 | # endif /* FEATURE_VI_SEARCH */ | 3520 | # endif /* FEATURE_VI_SEARCH */ |
| 3525 | } else if (strncmp(cmd, "version", i) == 0) { // show software version | 3521 | } else if (strncmp(cmd, "version", cmdlen) == 0) { // show software version |
| 3526 | status_line(BB_VER); | 3522 | status_line(BB_VER); |
| 3527 | } else if (strncmp(cmd, "write", i) == 0 // write text to file | 3523 | } else if (strncmp(cmd, "write", cmdlen) == 0 // write text to file |
| 3528 | || strcmp(cmd, "wq") == 0 | 3524 | || strcmp(cmd, "wq") == 0 |
| 3529 | || strcmp(cmd, "wn") == 0 | 3525 | || strcmp(cmd, "wn") == 0 |
| 3530 | || (cmd[0] == 'x' && !cmd[1]) | 3526 | || (cmd[0] == 'x' && !cmd[1]) |
| 3531 | ) { | 3527 | ) { |
| 3532 | int size; | 3528 | int size, l; |
| 3533 | //int forced = FALSE; | 3529 | //int forced = FALSE; |
| 3530 | char *fn = current_filename; | ||
| 3534 | 3531 | ||
| 3535 | // is there a file name to write to? | 3532 | // is there a file name to write to? |
| 3536 | if (args[0]) { | 3533 | if (args[0]) { |
| @@ -3539,8 +3536,10 @@ static void colon(char *buf) | |||
| 3539 | exp = expand_args(args); | 3536 | exp = expand_args(args); |
| 3540 | if (exp == NULL) | 3537 | if (exp == NULL) |
| 3541 | goto ret; | 3538 | goto ret; |
| 3542 | if (!useforce && (fn == NULL || strcmp(fn, exp) != 0) && | 3539 | if (!useforce |
| 3543 | stat(exp, &statbuf) == 0) { | 3540 | && (fn == NULL || strcmp(fn, exp) != 0) |
| 3541 | && stat(exp, &statbuf) == 0 | ||
| 3542 | ) { | ||
| 3544 | status_line_bold("File exists (:w! overrides)"); | 3543 | status_line_bold("File exists (:w! overrides)"); |
| 3545 | goto ret; | 3544 | goto ret; |
| 3546 | } | 3545 | } |
| @@ -3559,12 +3558,10 @@ static void colon(char *buf) | |||
| 3559 | // system(syscmd); | 3558 | // system(syscmd); |
| 3560 | // forced = TRUE; | 3559 | // forced = TRUE; |
| 3561 | //} | 3560 | //} |
| 3561 | size = l = 0; | ||
| 3562 | if (modified_count != 0 || cmd[0] != 'x') { | 3562 | if (modified_count != 0 || cmd[0] != 'x') { |
| 3563 | size = r - q + 1; | 3563 | size = r - q + 1; |
| 3564 | l = file_write(fn, q, r); | 3564 | l = file_write(fn, q, r); |
| 3565 | } else { | ||
| 3566 | size = 0; | ||
| 3567 | l = 0; | ||
| 3568 | } | 3565 | } |
| 3569 | //if (useforce && forced) { | 3566 | //if (useforce && forced) { |
| 3570 | // chmod u-w | 3567 | // chmod u-w |
| @@ -3577,8 +3574,8 @@ static void colon(char *buf) | |||
| 3577 | status_line_bold_errno(fn); | 3574 | status_line_bold_errno(fn); |
| 3578 | } else { | 3575 | } else { |
| 3579 | // how many lines written | 3576 | // how many lines written |
| 3580 | li = count_lines(q, q + l - 1); | 3577 | int lines = count_lines(q, q + l - 1); |
| 3581 | status_line("'%s' %uL, %uC", fn, li, l); | 3578 | status_line("'%s' %uL, %uC", fn, lines, l); |
| 3582 | if (l == size) { | 3579 | if (l == size) { |
| 3583 | if (q == text && q + l == end) { | 3580 | if (q == text && q + l == end) { |
| 3584 | modified_count = 0; | 3581 | modified_count = 0; |
| @@ -3590,37 +3587,35 @@ static void colon(char *buf) | |||
| 3590 | // are there other files to edit? | 3587 | // are there other files to edit? |
| 3591 | int n = cmdline_filecnt - optind - 1; | 3588 | int n = cmdline_filecnt - optind - 1; |
| 3592 | if (n > 0) { | 3589 | if (n > 0) { |
| 3593 | if (useforce) { | 3590 | if (!useforce) { |
| 3594 | // force end of argv list | ||
| 3595 | optind = cmdline_filecnt; | ||
| 3596 | } else { | ||
| 3597 | status_line_bold("%u more file(s) to edit", n); | 3591 | status_line_bold("%u more file(s) to edit", n); |
| 3598 | goto ret; | 3592 | goto ret; |
| 3599 | } | 3593 | } |
| 3594 | // force end of argv list | ||
| 3595 | optind = cmdline_filecnt; | ||
| 3600 | } | 3596 | } |
| 3601 | editing = 0; | 3597 | editing = 0; |
| 3602 | } | 3598 | } |
| 3603 | } | 3599 | } |
| 3604 | } | 3600 | } |
| 3605 | # if ENABLE_FEATURE_VI_YANKMARK | 3601 | # if ENABLE_FEATURE_VI_YANKMARK |
| 3606 | } else if (strncmp(cmd, "yank", i) == 0) { // yank lines | 3602 | } else if (strncmp(cmd, "yank", cmdlen) == 0) { // yank lines |
| 3603 | int lines; | ||
| 3607 | if (!GOT_ADDRESS) { // no addr given- use defaults | 3604 | if (!GOT_ADDRESS) { // no addr given- use defaults |
| 3608 | q = begin_line(dot); // assume .,. for the range | 3605 | q = begin_line(dot); // assume .,. for the range |
| 3609 | r = end_line(dot); | 3606 | r = end_line(dot); |
| 3610 | } | 3607 | } |
| 3611 | text_yank(q, r, YDreg, WHOLE); | 3608 | text_yank(q, r, YDreg, WHOLE); |
| 3612 | li = count_lines(q, r); | 3609 | lines = count_lines(q, r); |
| 3613 | status_line("Yank %d lines (%d chars) into [%c]", | 3610 | status_line("Yank %d lines (%d chars) into [%c]", |
| 3614 | li, strlen(reg[YDreg]), what_reg()); | 3611 | lines, strlen(reg[YDreg]), what_reg()); |
| 3615 | # endif | 3612 | # endif |
| 3616 | } else { | 3613 | } else { |
| 3617 | // cmd unknown | 3614 | // cmd unknown |
| 3618 | not_implemented(cmd); | 3615 | not_implemented(cmd); |
| 3619 | } | 3616 | } |
| 3620 | ret: | 3617 | ret: |
| 3621 | # if ENABLE_FEATURE_VI_COLON_EXPAND | 3618 | IF_FEATURE_VI_COLON_EXPAND(free(exp);) |
| 3622 | free(exp); | ||
| 3623 | # endif | ||
| 3624 | dot = bound_dot(dot); // make sure "dot" is valid | 3619 | dot = bound_dot(dot); // make sure "dot" is valid |
| 3625 | return; | 3620 | return; |
| 3626 | # if ENABLE_FEATURE_VI_SEARCH | 3621 | # if ENABLE_FEATURE_VI_SEARCH |
| @@ -4977,8 +4972,7 @@ static void run_cmds(char *p) | |||
| 4977 | if (p) | 4972 | if (p) |
| 4978 | while (*p == '\n') | 4973 | while (*p == '\n') |
| 4979 | *p++ = '\0'; | 4974 | *p++ = '\0'; |
| 4980 | if (strlen(q) < MAX_INPUT_LEN) | 4975 | colon(q); |
| 4981 | colon(q); | ||
| 4982 | } | 4976 | } |
| 4983 | } | 4977 | } |
| 4984 | #endif | 4978 | #endif |
diff --git a/include/libbb.h b/include/libbb.h index 6c4fe17c9..6ce99abda 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -457,7 +457,12 @@ unsigned FAST_FUNC bb_popcnt_long(unsigned long m); | |||
| 457 | #define bb_popcnt_long(m) bb_popcnt_32(m) | 457 | #define bb_popcnt_long(m) bb_popcnt_32(m) |
| 458 | #endif | 458 | #endif |
| 459 | 459 | ||
| 460 | unsigned long FAST_FUNC isqrt(unsigned long long N); | 460 | unsigned FAST_FUNC isqrt(unsigned long N); |
| 461 | #if LLONG_MAX > LONG_MAX | ||
| 462 | unsigned long FAST_FUNC isqrt_ull(unsigned long long N); | ||
| 463 | #else | ||
| 464 | # define isqrt_ull(N) isqrt(N) | ||
| 465 | #endif | ||
| 461 | 466 | ||
| 462 | unsigned long long monotonic_ns(void) FAST_FUNC; | 467 | unsigned long long monotonic_ns(void) FAST_FUNC; |
| 463 | unsigned long long monotonic_us(void) FAST_FUNC; | 468 | unsigned long long monotonic_us(void) FAST_FUNC; |
| @@ -1042,6 +1047,8 @@ int parse_pasv_epsv(char *buf) FAST_FUNC; | |||
| 1042 | /* 0 if argv[0] is NULL: */ | 1047 | /* 0 if argv[0] is NULL: */ |
| 1043 | unsigned string_array_len(char **argv) FAST_FUNC; | 1048 | unsigned string_array_len(char **argv) FAST_FUNC; |
| 1044 | void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; | 1049 | void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; |
| 1050 | /* Like strncpy but make sure the resulting string is always 0 terminated: */ | ||
| 1051 | /* writes SIZE chars, the [SIZE-1] char is always NUL (unless SIZE==0). */ | ||
| 1045 | char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; | 1052 | char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; |
| 1046 | char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; | 1053 | char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; |
| 1047 | unsigned count_strstr(const char *str, const char *sub) FAST_FUNC; | 1054 | unsigned count_strstr(const char *str, const char *sub) FAST_FUNC; |
| @@ -1053,6 +1060,8 @@ int bb_putchar(int ch) FAST_FUNC; | |||
| 1053 | int bb_putchar_stderr(char ch) FAST_FUNC; | 1060 | int bb_putchar_stderr(char ch) FAST_FUNC; |
| 1054 | int fputs_stdout(const char *s) FAST_FUNC; | 1061 | int fputs_stdout(const char *s) FAST_FUNC; |
| 1055 | char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) RETURNS_MALLOC; | 1062 | char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) RETURNS_MALLOC; |
| 1063 | char *xasprintf_and_free(char *allocated, const char *format, ...) __attribute__ ((format(printf, 2, 3))) RETURNS_MALLOC; | ||
| 1064 | #define xasprintf_inplace(allocated, ...) ((allocated) = xasprintf_and_free((allocated), __VA_ARGS__)) | ||
| 1056 | char *auto_string(char *str) FAST_FUNC; | 1065 | char *auto_string(char *str) FAST_FUNC; |
| 1057 | // gcc-4.1.1 still isn't good enough at optimizing it | 1066 | // gcc-4.1.1 still isn't good enough at optimizing it |
| 1058 | // (+200 bytes compared to macro) | 1067 | // (+200 bytes compared to macro) |
diff --git a/klibc-utils/resume.c b/klibc-utils/resume.c index 7b9d18b5d..179413627 100644 --- a/klibc-utils/resume.c +++ b/klibc-utils/resume.c | |||
| @@ -39,7 +39,7 @@ static dev_t name_to_dev_t(const char *devname) | |||
| 39 | struct stat st; | 39 | struct stat st; |
| 40 | int r; | 40 | int r; |
| 41 | 41 | ||
| 42 | if (strncmp(devname, "/dev/", 5) != 0) { | 42 | if (!is_prefixed_with(devname, "/dev/")) { |
| 43 | char *cptr; | 43 | char *cptr; |
| 44 | 44 | ||
| 45 | cptr = strchr(devname, ':'); | 45 | cptr = strchr(devname, ':'); |
| @@ -59,7 +59,7 @@ static dev_t name_to_dev_t(const char *devname) | |||
| 59 | return res; | 59 | return res; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | devname = xasprintf("/dev/%s", devname); | 62 | devname = concat_path_file("/dev", devname); |
| 63 | } | 63 | } |
| 64 | /* Now devname is always "/dev/FOO" */ | 64 | /* Now devname is always "/dev/FOO" */ |
| 65 | 65 | ||
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index b2dcf93e0..481cc278e 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
| @@ -1413,8 +1413,11 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
| 1413 | # endif | 1413 | # endif |
| 1414 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); | 1414 | lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); |
| 1415 | # if !ENABLE_BUSYBOX | 1415 | # if !ENABLE_BUSYBOX |
| 1416 | if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) | 1416 | if (argv[1] && argv[1][0] != '-' /* do not match "busybox --OPT" */ |
| 1417 | && is_prefixed_with(bb_basename(argv[0]), "busybox") | ||
| 1418 | ) { | ||
| 1417 | argv++; | 1419 | argv++; |
| 1420 | } | ||
| 1418 | # endif | 1421 | # endif |
| 1419 | applet_name = argv[0]; | 1422 | applet_name = argv[0]; |
| 1420 | if (applet_name[0] == '-') | 1423 | if (applet_name[0] == '-') |
diff --git a/libbb/isqrt.c b/libbb/isqrt.c index 817b7d036..507c7d637 100644 --- a/libbb/isqrt.c +++ b/libbb/isqrt.c | |||
| @@ -9,15 +9,42 @@ | |||
| 9 | #ifndef ISQRT_TEST | 9 | #ifndef ISQRT_TEST |
| 10 | # include "libbb.h" | 10 | # include "libbb.h" |
| 11 | #else | 11 | #else |
| 12 | /* gcc -DISQRT_TEST -Wall -O2 isqrt.c -oisqrt && ./isqrt $((RANDOM*RANDOM)) */ | 12 | // gcc -DISQRT_TEST -Wall -Os -ffunction-sections isqrt.c -S -fverbose-asm |
| 13 | // gcc -DISQRT_TEST -Wall -Os -ffunction-sections isqrt.c -c | ||
| 14 | // gcc -DISQRT_TEST -Wall -Os -ffunction-sections isqrt.c -oisqrt && ./isqrt $((RANDOM*RANDOM)) | ||
| 13 | # include <stdlib.h> | 15 | # include <stdlib.h> |
| 14 | # include <stdio.h> | 16 | # include <stdio.h> |
| 15 | # include <time.h> | 17 | # include <time.h> |
| 18 | # include <limits.h> | ||
| 16 | # define FAST_FUNC /* nothing */ | 19 | # define FAST_FUNC /* nothing */ |
| 17 | #endif | 20 | #endif |
| 18 | 21 | ||
| 19 | /* Returns such x that x+1 > sqrt(N) */ | 22 | /* Returns such x that x+1 > sqrt(N) */ |
| 20 | unsigned long FAST_FUNC isqrt(unsigned long long N) | 23 | |
| 24 | /* Stolen from kernel code */ | ||
| 25 | unsigned FAST_FUNC isqrt(unsigned long x) | ||
| 26 | { | ||
| 27 | unsigned long y = 0; | ||
| 28 | unsigned long m = 1UL << (8*sizeof(x) - 2); | ||
| 29 | // ^^^^^ should be m = 1UL << ((fls(x) - 1) & ~1UL); | ||
| 30 | // but calculating fls() would take time and code | ||
| 31 | |||
| 32 | do { | ||
| 33 | unsigned long b = y + m; | ||
| 34 | y >>= 1; | ||
| 35 | if (x >= b) { | ||
| 36 | x -= b; | ||
| 37 | y += m; | ||
| 38 | } | ||
| 39 | m >>= 2; | ||
| 40 | } while (m); | ||
| 41 | return y; | ||
| 42 | } | ||
| 43 | |||
| 44 | #if LLONG_MAX > LONG_MAX | ||
| 45 | # if defined(i386) | ||
| 46 | /* Smaller code on this register-starved arch */ | ||
| 47 | unsigned long FAST_FUNC isqrt_ull(unsigned long long N) | ||
| 21 | { | 48 | { |
| 22 | unsigned long x; | 49 | unsigned long x; |
| 23 | unsigned shift; | 50 | unsigned shift; |
| @@ -33,15 +60,40 @@ unsigned long FAST_FUNC isqrt(unsigned long long N) | |||
| 33 | } while ((int)shift >= 0); | 60 | } while ((int)shift >= 0); |
| 34 | return x; | 61 | return x; |
| 35 | } | 62 | } |
| 63 | # else | ||
| 64 | /* Stolen from kernel code */ | ||
| 65 | unsigned long FAST_FUNC isqrt_ull(unsigned long long x) | ||
| 66 | { | ||
| 67 | unsigned long long y = 0; | ||
| 68 | unsigned long long m = 1ULL << (8*sizeof(x) - 2); | ||
| 69 | // ^^^^^ should be m = 1ULL << ((fls(x) - 1) & ~1ULL); | ||
| 70 | // but calculating fls() would take time and code | ||
| 71 | |||
| 72 | do { | ||
| 73 | unsigned long long b = y + m; | ||
| 74 | y >>= 1; | ||
| 75 | if (x >= b) { | ||
| 76 | x -= b; | ||
| 77 | y += m; | ||
| 78 | } | ||
| 79 | m >>= 2; | ||
| 80 | } while (m); | ||
| 81 | return y; | ||
| 82 | } | ||
| 83 | # endif | ||
| 84 | #endif /* wide version needed */ | ||
| 36 | 85 | ||
| 37 | #ifdef ISQRT_TEST | 86 | #ifdef ISQRT_TEST |
| 87 | # if LLONG_MAX == LONG_MAX | ||
| 88 | # define isqrt_ull(N) isqrt(N) | ||
| 89 | # endif | ||
| 38 | int main(int argc, char **argv) | 90 | int main(int argc, char **argv) |
| 39 | { | 91 | { |
| 40 | unsigned long long n = argv[1] ? strtoull(argv[1], NULL, 0) : time(NULL); | 92 | unsigned long long n = argv[1] ? strtoull(argv[1], NULL, 0) : time(NULL); |
| 41 | for (;;) { | 93 | for (;;) { |
| 42 | unsigned long h; | 94 | unsigned long h; |
| 43 | n--; | 95 | n--; |
| 44 | h = isqrt(n); | 96 | h = isqrt_ull(n); |
| 45 | if (!(n & 0xffff)) | 97 | if (!(n & 0xffff)) |
| 46 | printf("isqrt(%llx)=%lx\n", n, h); | 98 | printf("isqrt(%llx)=%lx\n", n, h); |
| 47 | if ((unsigned long long)h * h > n) { | 99 | if ((unsigned long long)h * h > n) { |
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 675c91d68..f4d1b913a 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c | |||
| @@ -351,6 +351,22 @@ char* xasprintf(const char *format, ...) | |||
| 351 | return string_ptr; | 351 | return string_ptr; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | char* xasprintf_and_free(char *allocated, const char *format, ...) | ||
| 355 | { | ||
| 356 | va_list p; | ||
| 357 | int r; | ||
| 358 | char *string_ptr; | ||
| 359 | |||
| 360 | va_start(p, format); | ||
| 361 | r = vasprintf(&string_ptr, format, p); | ||
| 362 | va_end(p); | ||
| 363 | |||
| 364 | if (r < 0) | ||
| 365 | bb_die_memory_exhausted(); | ||
| 366 | free(allocated); | ||
| 367 | return string_ptr; | ||
| 368 | } | ||
| 369 | |||
| 354 | void FAST_FUNC xsetenv(const char *key, const char *value) | 370 | void FAST_FUNC xsetenv(const char *key, const char *value) |
| 355 | { | 371 | { |
| 356 | if (setenv(key, value, 1)) | 372 | if (setenv(key, value, 1)) |
diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index 2470050e7..ff54ab5db 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c | |||
| @@ -64,7 +64,6 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
| 64 | if (orig_fp) | 64 | if (orig_fp) |
| 65 | xfstat(fileno(orig_fp), &sb, orig_fn); | 65 | xfstat(fileno(orig_fp), &sb, orig_fn); |
| 66 | 66 | ||
| 67 | |||
| 68 | new_fn = xasprintf("%s.tmp", orig_fn); | 67 | new_fn = xasprintf("%s.tmp", orig_fn); |
| 69 | /* | 68 | /* |
| 70 | * O_TRUNC or O_EXCL? At the first glance, O_EXCL looks better, | 69 | * O_TRUNC or O_EXCL? At the first glance, O_EXCL looks better, |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index bfab05203..ac43feb48 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
| @@ -227,7 +227,7 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) | |||
| 227 | die_if_bad_username(pw.pw_name); | 227 | die_if_bad_username(pw.pw_name); |
| 228 | if (!pw.pw_dir) { | 228 | if (!pw.pw_dir) { |
| 229 | /* create string for $HOME if not specified already */ | 229 | /* create string for $HOME if not specified already */ |
| 230 | pw.pw_dir = xasprintf("/home/%s", argv[0]); | 230 | pw.pw_dir = concat_path_file("/home", argv[0]); |
| 231 | } | 231 | } |
| 232 | pw.pw_passwd = (char *)"x"; | 232 | pw.pw_passwd = (char *)"x"; |
| 233 | if (opts & OPT_SYSTEM_ACCOUNT) { | 233 | if (opts & OPT_SYSTEM_ACCOUNT) { |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 4581cc9f7..67a08f487 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
| @@ -213,7 +213,7 @@ static void open_tty(void) | |||
| 213 | /* Set up new standard input, unless we are given an already opened port */ | 213 | /* Set up new standard input, unless we are given an already opened port */ |
| 214 | if (NOT_LONE_DASH(G.tty_name)) { | 214 | if (NOT_LONE_DASH(G.tty_name)) { |
| 215 | if (G.tty_name[0] != '/') | 215 | if (G.tty_name[0] != '/') |
| 216 | G.tty_name = xasprintf("/dev/%s", G.tty_name); /* will leak it */ | 216 | G.tty_name = concat_path_file("/dev", G.tty_name); /* will leak it */ |
| 217 | 217 | ||
| 218 | /* Open the tty as standard input */ | 218 | /* Open the tty as standard input */ |
| 219 | debug("open(2)\n"); | 219 | debug("open(2)\n"); |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 642cd3637..d57691414 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
| @@ -962,7 +962,6 @@ static void action_compat(const struct devfsd_notify_struct *info, unsigned int | |||
| 962 | dest_name = dest_buf; | 962 | dest_name = dest_buf; |
| 963 | compat_name = compat_buf; | 963 | compat_name = compat_buf; |
| 964 | 964 | ||
| 965 | |||
| 966 | /* 1 == scsi/generic 2 == scsi/disc 3 == scsi/cd 6 == ide/host/disc 7 == ide/host/cd */ | 965 | /* 1 == scsi/generic 2 == scsi/disc 3 == scsi/cd 6 == ide/host/disc 7 == ide/host/cd */ |
| 967 | if (i == 1 || i == 2 || i == 3 || i == 6 || i ==7) | 966 | if (i == 1 || i == 2 || i == 3 || i == 6 || i ==7) |
| 968 | sprintf(compat_buf, fmt[i], host, bus, target, lun); | 967 | sprintf(compat_buf, fmt[i], host, bus, target, lun); |
diff --git a/miscutils/less.c b/miscutils/less.c index 5a8fc5a74..91403a252 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
| @@ -857,13 +857,13 @@ static void print_found(const char *line) | |||
| 857 | goto start; | 857 | goto start; |
| 858 | 858 | ||
| 859 | while (match_status == 0) { | 859 | while (match_status == 0) { |
| 860 | char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, | 860 | xasprintf_inplace(growline, |
| 861 | growline ? growline : "", | 861 | "%s%.*s"HIGHLIGHT"%.*s"NORMAL, |
| 862 | (int)match_structs.rm_so, str, | 862 | growline ? growline : "", |
| 863 | (int)(match_structs.rm_eo - match_structs.rm_so), | 863 | (int)match_structs.rm_so, |
| 864 | str + match_structs.rm_so); | 864 | str, |
| 865 | free(growline); | 865 | (int)(match_structs.rm_eo - match_structs.rm_so), |
| 866 | growline = new; | 866 | str + match_structs.rm_so); |
| 867 | str += match_structs.rm_eo; | 867 | str += match_structs.rm_eo; |
| 868 | line += match_structs.rm_eo; | 868 | line += match_structs.rm_eo; |
| 869 | eflags = REG_NOTBOL; | 869 | eflags = REG_NOTBOL; |
diff --git a/miscutils/man.c b/miscutils/man.c index 38c1b9aa3..cf67f1538 100644 --- a/miscutils/man.c +++ b/miscutils/man.c | |||
| @@ -73,7 +73,7 @@ struct globals { | |||
| 73 | 73 | ||
| 74 | static int show_manpage(char *man_filename, int man, int level); | 74 | static int show_manpage(char *man_filename, int man, int level); |
| 75 | 75 | ||
| 76 | static int run_pipe(char *man_filename, int man, int level) | 76 | static int run_man_pipe(char *man_filename, int man, int level) |
| 77 | { | 77 | { |
| 78 | char *cmd; | 78 | char *cmd; |
| 79 | 79 | ||
| @@ -115,24 +115,36 @@ static int run_pipe(char *man_filename, int man, int level) | |||
| 115 | * ".so man7/path_resolution.7\n<junk>" | 115 | * ".so man7/path_resolution.7\n<junk>" |
| 116 | */ | 116 | */ |
| 117 | *strchrnul(line, '\n') = '\0'; | 117 | *strchrnul(line, '\n') = '\0'; |
| 118 | linkname = skip_whitespace(&line[4]); | 118 | linkname = skip_whitespace(line + 4); |
| 119 | 119 | //testcase: | |
| 120 | /* If link has no slashes, we just replace man page name. | 120 | // cd /usr/share/man/man2 |
| 121 | * If link has slashes (however many), we go back *once*. | 121 | // man ./path_resolution.2.gz |
| 122 | * ".so zzz/ggg/page.3" does NOT go back two levels. */ | 122 | while (man_filename[0] == '.' && man_filename[1] == '/') |
| 123 | man_filename += 2; | ||
| 123 | p = strrchr(man_filename, '/'); | 124 | p = strrchr(man_filename, '/'); |
| 124 | if (!p) | 125 | if (!p) |
| 125 | goto ordinary_manpage; | 126 | man_filename = (char*)".." + 1; /* "NAME.N" -> "." */ |
| 126 | *p = '\0'; | 127 | else |
| 128 | *p = '\0'; /* "PFX/manN/NAME.N" -> "PFX/manN" */ | ||
| 129 | |||
| 130 | /* If link has slashes (however many), we go back *once*. | ||
| 131 | * ".so zzz/ggg/page.3" does NOT go back two levels. | ||
| 132 | */ | ||
| 127 | if (strchr(linkname, '/')) { | 133 | if (strchr(linkname, '/')) { |
| 134 | if (!p) { /* man_filename had no path */ | ||
| 135 | man_filename--; /* ".." */ | ||
| 136 | goto append_link; | ||
| 137 | } | ||
| 128 | p = strrchr(man_filename, '/'); | 138 | p = strrchr(man_filename, '/'); |
| 129 | if (!p) | 139 | if (!p) |
| 130 | goto ordinary_manpage; | 140 | man_filename = (char*)".." + 1; /* "manN" -> "." */ |
| 131 | *p = '\0'; | 141 | else |
| 132 | } | 142 | *p = '\0'; /* "PFX/manN" -> "PFX" */ |
| 143 | } /* else (link has no slashes): will do "PFX/manN" -> "PFX/manN/link" */ | ||
| 133 | 144 | ||
| 134 | /* Links do not have .gz extensions, even if manpage | 145 | /* Links do not have .gz extensions, even if manpage |
| 135 | * is compressed */ | 146 | * is compressed */ |
| 147 | append_link: | ||
| 136 | man_filename = xasprintf("%s/%s", man_filename, linkname); | 148 | man_filename = xasprintf("%s/%s", man_filename, linkname); |
| 137 | free(line); | 149 | free(line); |
| 138 | /* Note: we leak "new" man_filename string as well... */ | 150 | /* Note: we leak "new" man_filename string as well... */ |
| @@ -172,26 +184,26 @@ static int show_manpage(char *man_filename, int man, int level) | |||
| 172 | #endif | 184 | #endif |
| 173 | 185 | ||
| 174 | #if ENABLE_FEATURE_SEAMLESS_LZMA | 186 | #if ENABLE_FEATURE_SEAMLESS_LZMA |
| 175 | if (run_pipe(filename_with_zext, man, level)) | 187 | if (run_man_pipe(filename_with_zext, man, level)) |
| 176 | return 1; | 188 | return 1; |
| 177 | #endif | 189 | #endif |
| 178 | #if ENABLE_FEATURE_SEAMLESS_XZ | 190 | #if ENABLE_FEATURE_SEAMLESS_XZ |
| 179 | strcpy(ext, "xz"); | 191 | strcpy(ext, "xz"); |
| 180 | if (run_pipe(filename_with_zext, man, level)) | 192 | if (run_man_pipe(filename_with_zext, man, level)) |
| 181 | return 1; | 193 | return 1; |
| 182 | #endif | 194 | #endif |
| 183 | #if ENABLE_FEATURE_SEAMLESS_BZ2 | 195 | #if ENABLE_FEATURE_SEAMLESS_BZ2 |
| 184 | strcpy(ext, "bz2"); | 196 | strcpy(ext, "bz2"); |
| 185 | if (run_pipe(filename_with_zext, man, level)) | 197 | if (run_man_pipe(filename_with_zext, man, level)) |
| 186 | return 1; | 198 | return 1; |
| 187 | #endif | 199 | #endif |
| 188 | #if ENABLE_FEATURE_SEAMLESS_GZ | 200 | #if ENABLE_FEATURE_SEAMLESS_GZ |
| 189 | strcpy(ext, "gz"); | 201 | strcpy(ext, "gz"); |
| 190 | if (run_pipe(filename_with_zext, man, level)) | 202 | if (run_man_pipe(filename_with_zext, man, level)) |
| 191 | return 1; | 203 | return 1; |
| 192 | #endif | 204 | #endif |
| 193 | 205 | ||
| 194 | return run_pipe(man_filename, man, level); | 206 | return run_man_pipe(man_filename, man, level); |
| 195 | } | 207 | } |
| 196 | 208 | ||
| 197 | static char **add_MANPATH(char **man_path_list, int *count_mp, char *path) | 209 | static char **add_MANPATH(char **man_path_list, int *count_mp, char *path) |
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 31a215a29..7f584102d 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
| @@ -723,7 +723,7 @@ static int process_module(char *name, const char *cmdline_options) | |||
| 723 | 723 | ||
| 724 | options = NULL; | 724 | options = NULL; |
| 725 | if (!is_remove) { | 725 | if (!is_remove) { |
| 726 | char *opt_filename = xasprintf("/etc/modules/%s", name); | 726 | char *opt_filename = concat_path_file("/etc/modules", name); |
| 727 | options = xmalloc_open_read_close(opt_filename, NULL); | 727 | options = xmalloc_open_read_close(opt_filename, NULL); |
| 728 | if (options) | 728 | if (options) |
| 729 | replace_char(options, '\n', ' '); | 729 | replace_char(options, '\n', ' '); |
| @@ -731,10 +731,8 @@ static int process_module(char *name, const char *cmdline_options) | |||
| 731 | if (cmdline_options) { | 731 | if (cmdline_options) { |
| 732 | /* NB: cmdline_options always have one leading ' ' | 732 | /* NB: cmdline_options always have one leading ' ' |
| 733 | * (see main()), we remove it here */ | 733 | * (see main()), we remove it here */ |
| 734 | char *op = xasprintf(options ? "%s %s" : "%s %s" + 3, | 734 | xasprintf_inplace(options, options ? "%s %s" : "%s %s" + 3, |
| 735 | cmdline_options + 1, options); | 735 | cmdline_options + 1, options); |
| 736 | free(options); | ||
| 737 | options = op; | ||
| 738 | } | 736 | } |
| 739 | #endif | 737 | #endif |
| 740 | free(opt_filename); | 738 | free(opt_filename); |
| @@ -1010,9 +1008,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
| 1010 | char **arg = argv; | 1008 | char **arg = argv; |
| 1011 | while (*++arg) { | 1009 | while (*++arg) { |
| 1012 | /* Enclose options in quotes */ | 1010 | /* Enclose options in quotes */ |
| 1013 | char *s = options; | 1011 | xasprintf_inplace(options, "%s \"%s\"", options ? options : "", *arg); |
| 1014 | options = xasprintf("%s \"%s\"", s ? s : "", *arg); | ||
| 1015 | free(s); | ||
| 1016 | *arg = NULL; | 1012 | *arg = NULL; |
| 1017 | } | 1013 | } |
| 1018 | # else | 1014 | # else |
diff --git a/networking/ftpd.c b/networking/ftpd.c index c3125410e..96db5d9fd 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
| @@ -491,19 +491,18 @@ static void | |||
| 491 | handle_pasv(void) | 491 | handle_pasv(void) |
| 492 | { | 492 | { |
| 493 | unsigned port; | 493 | unsigned port; |
| 494 | char *addr, *response; | 494 | char *response; |
| 495 | 495 | ||
| 496 | port = bind_for_passive_mode(); | 496 | port = bind_for_passive_mode(); |
| 497 | 497 | ||
| 498 | if (G.local_addr->u.sa.sa_family == AF_INET) | 498 | if (G.local_addr->u.sa.sa_family == AF_INET) |
| 499 | addr = xmalloc_sockaddr2dotted_noport(&G.local_addr->u.sa); | 499 | response = xmalloc_sockaddr2dotted_noport(&G.local_addr->u.sa); |
| 500 | else /* seen this in the wild done by other ftp servers: */ | 500 | else /* seen this in the wild done by other ftp servers: */ |
| 501 | addr = xstrdup("0.0.0.0"); | 501 | response = xstrdup("0.0.0.0"); |
| 502 | replace_char(addr, '.', ','); | 502 | replace_char(response, '.', ','); |
| 503 | 503 | ||
| 504 | response = xasprintf(STR(FTP_PASVOK)" PASV ok (%s,%u,%u)\r\n", | 504 | xasprintf_inplace(response, STR(FTP_PASVOK)" PASV ok (%s,%u,%u)\r\n", |
| 505 | addr, (int)(port >> 8), (int)(port & 255)); | 505 | response, (int)(port >> 8), (int)(port & 255)); |
| 506 | free(addr); | ||
| 507 | cmdio_write_raw(response); | 506 | cmdio_write_raw(response); |
| 508 | free(response); | 507 | free(response); |
| 509 | } | 508 | } |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 9c3640be7..bc2dca506 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
| @@ -895,16 +895,15 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in | |||
| 895 | while ((buf = xmalloc_fgetline(f)) != NULL) { | 895 | while ((buf = xmalloc_fgetline(f)) != NULL) { |
| 896 | #if ENABLE_DESKTOP | 896 | #if ENABLE_DESKTOP |
| 897 | /* Trailing "\" concatenates lines */ | 897 | /* Trailing "\" concatenates lines */ |
| 898 | //TODO: check how to handle "line\\" (double backslashes) | ||
| 898 | char *p; | 899 | char *p; |
| 899 | while ((p = last_char_is(buf, '\\')) != NULL) { | 900 | while ((p = last_char_is(buf, '\\')) != NULL) { |
| 900 | *p = '\0'; | 901 | *p = '\0'; |
| 901 | rest_of_line = xmalloc_fgetline(f); | 902 | rest_of_line = xmalloc_fgetline(f); |
| 902 | if (!rest_of_line) | 903 | if (!rest_of_line) |
| 903 | break; | 904 | break; |
| 904 | p = xasprintf("%s%s", buf, rest_of_line); | 905 | xasprintf_inplace(buf, "%s%s", buf, rest_of_line); |
| 905 | free(buf); | ||
| 906 | free(rest_of_line); | 906 | free(rest_of_line); |
| 907 | buf = p; | ||
| 908 | } | 907 | } |
| 909 | #endif | 908 | #endif |
| 910 | rest_of_line = buf; | 909 | rest_of_line = buf; |
diff --git a/networking/netstat.c b/networking/netstat.c index 807800a62..d7afa8fdd 100644 --- a/networking/netstat.c +++ b/networking/netstat.c | |||
| @@ -391,7 +391,7 @@ static const char *get_sname(int port, const char *proto, int numeric) | |||
| 391 | 391 | ||
| 392 | static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int numeric) | 392 | static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int numeric) |
| 393 | { | 393 | { |
| 394 | char *host, *host_port; | 394 | char *host; |
| 395 | 395 | ||
| 396 | /* Code which used "*" for INADDR_ANY is removed: it's ambiguous | 396 | /* Code which used "*" for INADDR_ANY is removed: it's ambiguous |
| 397 | * in IPv6, while "0.0.0.0" is not. */ | 397 | * in IPv6, while "0.0.0.0" is not. */ |
| @@ -402,9 +402,8 @@ static char *ip_port_str(struct sockaddr *addr, int port, const char *proto, int | |||
| 402 | if (!host) | 402 | if (!host) |
| 403 | host = xmalloc_sockaddr2dotted_noport(addr); | 403 | host = xmalloc_sockaddr2dotted_noport(addr); |
| 404 | 404 | ||
| 405 | host_port = xasprintf("%s:%s", host, get_sname(htons(port), proto, numeric)); | 405 | xasprintf_inplace(host, "%s:%s", host, get_sname(htons(port), proto, numeric)); |
| 406 | free(host); | 406 | return host; |
| 407 | return host_port; | ||
| 408 | } | 407 | } |
| 409 | 408 | ||
| 410 | struct inet_params { | 409 | struct inet_params { |
diff --git a/networking/ntpd.c b/networking/ntpd.c index efe9f5326..595000b11 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
| @@ -2395,7 +2395,7 @@ static NOINLINE void ntp_init(char **argv) | |||
| 2395 | while (peers) { | 2395 | while (peers) { |
| 2396 | char *peer = llist_pop(&peers); | 2396 | char *peer = llist_pop(&peers); |
| 2397 | key_entry_t *key_entry = NULL; | 2397 | key_entry_t *key_entry = NULL; |
| 2398 | if (strncmp(peer, "keyno:", 6) == 0) { | 2398 | if (is_prefixed_with(peer, "keyno:")) { |
| 2399 | char *end; | 2399 | char *end; |
| 2400 | int key_id; | 2400 | int key_id; |
| 2401 | peer += 6; | 2401 | peer += 6; |
diff --git a/networking/tls.h b/networking/tls.h index eee5a7617..fde2e4d3d 100644 --- a/networking/tls.h +++ b/networking/tls.h | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | */ | 10 | */ |
| 11 | #include "libbb.h" | 11 | #include "libbb.h" |
| 12 | 12 | ||
| 13 | |||
| 14 | #if !ENABLE_FEATURE_TLS_SCHANNEL | 13 | #if !ENABLE_FEATURE_TLS_SCHANNEL |
| 15 | /* Config tweaks */ | 14 | /* Config tweaks */ |
| 16 | #define HAVE_NATIVE_INT64 | 15 | #define HAVE_NATIVE_INT64 |
| @@ -32,16 +31,18 @@ | |||
| 32 | # define PSTM_32BIT | 31 | # define PSTM_32BIT |
| 33 | # define PSTM_X86 | 32 | # define PSTM_X86 |
| 34 | #endif | 33 | #endif |
| 35 | //#if defined(__GNUC__) && defined(__x86_64__) | 34 | #if defined(__GNUC__) && defined(__x86_64__) |
| 36 | // /* PSTM_X86_64 works correctly, but +782 bytes. */ | 35 | /* PSTM_64BIT + PSTM_X86_64 works correctly, but: |
| 37 | // /* Looks like most of the growth is because of PSTM_64BIT. */ | 36 | * +928 bytes if PSTM_64BIT but !PSTM_X86_64 |
| 37 | * +1003 bytes with INNERMUL8 (loop unrolling in pstm_montgomery_reduce()) | ||
| 38 | * +664 bytes without INNERMUL8 | ||
| 39 | */ | ||
| 38 | //# define PSTM_64BIT | 40 | //# define PSTM_64BIT |
| 39 | //# define PSTM_X86_64 | 41 | //# define PSTM_X86_64 |
| 40 | //#endif | 42 | #endif |
| 41 | //#if SOME_COND #define PSTM_MIPS, #define PSTM_32BIT | 43 | //#if SOME_COND #define PSTM_MIPS, #define PSTM_32BIT |
| 42 | //#if SOME_COND #define PSTM_ARM, #define PSTM_32BIT | 44 | //#if SOME_COND #define PSTM_ARM, #define PSTM_32BIT |
| 43 | 45 | ||
| 44 | |||
| 45 | #define PS_SUCCESS 0 | 46 | #define PS_SUCCESS 0 |
| 46 | #define PS_FAILURE -1 | 47 | #define PS_FAILURE -1 |
| 47 | #define PS_ARG_FAIL -6 /* Failure due to bad function param */ | 48 | #define PS_ARG_FAIL -6 /* Failure due to bad function param */ |
| @@ -52,14 +53,14 @@ | |||
| 52 | #define PS_TRUE 1 | 53 | #define PS_TRUE 1 |
| 53 | #define PS_FALSE 0 | 54 | #define PS_FALSE 0 |
| 54 | 55 | ||
| 56 | #undef ENDIAN_BIG | ||
| 57 | #undef ENDIAN_LITTLE | ||
| 55 | #if BB_BIG_ENDIAN | 58 | #if BB_BIG_ENDIAN |
| 56 | # define ENDIAN_BIG 1 | 59 | # define ENDIAN_BIG 1 |
| 57 | # undef ENDIAN_LITTLE | ||
| 58 | //#???? ENDIAN_32BITWORD | 60 | //#???? ENDIAN_32BITWORD |
| 59 | // controls only STORE32L, which we don't use | 61 | // controls only STORE32L, which we don't use |
| 60 | #else | 62 | #else |
| 61 | # define ENDIAN_LITTLE 1 | 63 | # define ENDIAN_LITTLE 1 |
| 62 | # undef ENDIAN_BIG | ||
| 63 | #endif | 64 | #endif |
| 64 | 65 | ||
| 65 | typedef uint64_t uint64; | 66 | typedef uint64_t uint64; |
| @@ -99,7 +100,6 @@ void tls_get_random(void *buf, unsigned len) FAST_FUNC; | |||
| 99 | #undef min | 100 | #undef min |
| 100 | #define min(x, y) ((x) < (y) ? (x) : (y)) | 101 | #define min(x, y) ((x) < (y) ? (x) : (y)) |
| 101 | 102 | ||
| 102 | |||
| 103 | #include "tls_pstm.h" | 103 | #include "tls_pstm.h" |
| 104 | #include "tls_aes.h" | 104 | #include "tls_aes.h" |
| 105 | #include "tls_aesgcm.h" | 105 | #include "tls_aesgcm.h" |
diff --git a/networking/tls_pstm_montgomery_reduce.c b/networking/tls_pstm_montgomery_reduce.c index 4181a0590..e63e590db 100644 --- a/networking/tls_pstm_montgomery_reduce.c +++ b/networking/tls_pstm_montgomery_reduce.c | |||
| @@ -135,7 +135,7 @@ asm( \ | |||
| 135 | :"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \ | 135 | :"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \ |
| 136 | : "%rax", "%rdx", "cc") | 136 | : "%rax", "%rdx", "cc") |
| 137 | 137 | ||
| 138 | #define INNERMUL8 \ | 138 | #define INNERMUL8_disabled_for_bbox \ |
| 139 | asm( \ | 139 | asm( \ |
| 140 | "movq 0(%5),%%rax \n\t" \ | 140 | "movq 0(%5),%%rax \n\t" \ |
| 141 | "movq 0(%2),%%r10 \n\t" \ | 141 | "movq 0(%2),%%r10 \n\t" \ |
| @@ -398,7 +398,7 @@ int32 FAST_FUNC pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, pstm_int *m, | |||
| 398 | _c = c + x; | 398 | _c = c + x; |
| 399 | tmpm = m->dp; | 399 | tmpm = m->dp; |
| 400 | y = 0; | 400 | y = 0; |
| 401 | #ifdef PSTM_X86_64 | 401 | #ifdef INNERMUL8 //bbox: PSTM_X86_64 |
| 402 | for (; y < (pa & ~7); y += 8) { | 402 | for (; y < (pa & ~7); y += 8) { |
| 403 | INNERMUL8; | 403 | INNERMUL8; |
| 404 | _c += 8; | 404 | _c += 8; |
diff --git a/procps/watch.c b/procps/watch.c index d7c3ad55e..51b324b44 100644 --- a/procps/watch.c +++ b/procps/watch.c | |||
| @@ -19,11 +19,12 @@ | |||
| 19 | //kbuild:lib-$(CONFIG_WATCH) += watch.o | 19 | //kbuild:lib-$(CONFIG_WATCH) += watch.o |
| 20 | 20 | ||
| 21 | //usage:#define watch_trivial_usage | 21 | //usage:#define watch_trivial_usage |
| 22 | //usage: "[-n SEC] [-t] PROG ARGS" | 22 | //usage: "[-n SEC] [-tx] PROG ARGS" |
| 23 | //usage:#define watch_full_usage "\n\n" | 23 | //usage:#define watch_full_usage "\n\n" |
| 24 | //usage: "Run PROG periodically\n" | 24 | //usage: "Run PROG periodically\n" |
| 25 | //usage: "\n -n SEC Period (default 2)" | 25 | //usage: "\n -n SEC Period (default 2)" |
| 26 | //usage: "\n -t Don't print header" | 26 | //usage: "\n -t Don't print header" |
| 27 | //usage: "\n -x exec(PROG,ARGS) instead of sh -c 'PROG ARGS'" | ||
| 27 | //usage: | 28 | //usage: |
| 28 | //usage:#define watch_example_usage | 29 | //usage:#define watch_example_usage |
| 29 | //usage: "$ watch date\n" | 30 | //usage: "$ watch date\n" |
| @@ -56,6 +57,7 @@ int watch_main(int argc UNUSED_PARAM, char **argv) | |||
| 56 | unsigned opt; | 57 | unsigned opt; |
| 57 | unsigned width, new_width; | 58 | unsigned width, new_width; |
| 58 | char *header; | 59 | char *header; |
| 60 | char **argv0; | ||
| 59 | char *cmd; | 61 | char *cmd; |
| 60 | 62 | ||
| 61 | #if 0 // maybe ENABLE_DESKTOP? | 63 | #if 0 // maybe ENABLE_DESKTOP? |
| @@ -66,27 +68,32 @@ int watch_main(int argc UNUSED_PARAM, char **argv) | |||
| 66 | 68 | ||
| 67 | // "+": stop at first non-option (procps 3.x only); -n NUM | 69 | // "+": stop at first non-option (procps 3.x only); -n NUM |
| 68 | // at least one param | 70 | // at least one param |
| 69 | opt = getopt32(argv, "^+" "dtn:" "\0" "-1", &period_str); | 71 | opt = getopt32(argv, "^+" "dtn:x" "\0" "-1", &period_str); |
| 70 | argv += optind; | 72 | argv += optind; |
| 71 | 73 | ||
| 72 | // watch from both procps 2.x and 3.x does concatenation. Example: | 74 | // watch from both procps 2.x and 3.x concatenates (unless -x). |
| 73 | // watch ls -l "a /tmp" "2>&1" - ls won't see "a /tmp" as one param | 75 | // Example: |
| 76 | // watch ls -l "a /tmp" "2>&1" - ls won't see "a /tmp" as one param. | ||
| 77 | argv0 = argv; | ||
| 78 | // If -x, cmd is only used for printing header | ||
| 74 | #if ENABLE_PLATFORM_MINGW32 | 79 | #if ENABLE_PLATFORM_MINGW32 |
| 75 | cmd = NULL; | 80 | cmd = NULL; |
| 76 | do { | 81 | do { |
| 77 | cmd = xappendword(cmd, *argv); | 82 | cmd = xappendword(cmd, *argv); |
| 78 | } while (*++argv); | 83 | } while (*++argv); |
| 79 | #else | 84 | #else |
| 80 | cmd = *argv; | 85 | cmd = xstrdup(*argv); |
| 81 | while (*++argv) | 86 | while (*++argv) |
| 82 | cmd = xasprintf("%s %s", cmd, *argv); // leaks cmd | 87 | xasprintf_inplace(cmd, "%s %s", cmd, *argv); |
| 83 | #endif | 88 | #endif |
| 89 | if (opt & (1 << 3)) | ||
| 90 | argv = argv0; // If -x, restore argv[0] to !NULL | ||
| 84 | 91 | ||
| 85 | period = parse_duration_str(period_str); | 92 | period = parse_duration_str(period_str); |
| 86 | width = (unsigned)-1; // make sure first time new_width != width | 93 | width = (unsigned)-1; // make sure first time new_width != width |
| 87 | header = NULL; | 94 | header = NULL; |
| 88 | while (1) { | 95 | while (1) { |
| 89 | /* home; clear to the end of screen */ | 96 | // home; clear to the end of screen |
| 90 | printf(ESC"[H" ESC"[J"); | 97 | printf(ESC"[H" ESC"[J"); |
| 91 | if (!(opt & 0x2)) { // no -t | 98 | if (!(opt & 0x2)) { // no -t |
| 92 | const unsigned time_len = sizeof("1234-67-90 23:56:89"); | 99 | const unsigned time_len = sizeof("1234-67-90 23:56:89"); |
| @@ -119,7 +126,10 @@ int watch_main(int argc UNUSED_PARAM, char **argv) | |||
| 119 | // TODO: 'real' watch pipes cmd's output to itself | 126 | // TODO: 'real' watch pipes cmd's output to itself |
| 120 | // and does not allow it to overflow the screen | 127 | // and does not allow it to overflow the screen |
| 121 | // (taking into account linewrap!) | 128 | // (taking into account linewrap!) |
| 122 | system(cmd); | 129 | if (argv[0]) // -x? |
| 130 | spawn_and_wait(argv); // yes | ||
| 131 | else | ||
| 132 | system(cmd); | ||
| 123 | sleep_for_duration(period); | 133 | sleep_for_duration(period); |
| 124 | } | 134 | } |
| 125 | return 0; // gcc thinks we can reach this :) | 135 | return 0; // gcc thinks we can reach this :) |
diff --git a/shell/ash.c b/shell/ash.c index 43f92bfae..bb8ac53d6 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -1384,7 +1384,7 @@ static void dbg_show_dirtymem(const char *msg) | |||
| 1384 | p = buf; | 1384 | p = buf; |
| 1385 | for (;;) { | 1385 | for (;;) { |
| 1386 | char *e = strchrnul(p, '\n'); | 1386 | char *e = strchrnul(p, '\n'); |
| 1387 | if (strncmp(p, "Private_Dirty:", 14) == 0) { | 1387 | if (is_prefixed_with(p, "Private_Dirty:")) { |
| 1388 | p = skip_whitespace(p + 14); | 1388 | p = skip_whitespace(p + 14); |
| 1389 | bb_error_msg("%s:%.*s", msg, (int)(e - p), p); | 1389 | bb_error_msg("%s:%.*s", msg, (int)(e - p), p); |
| 1390 | break; | 1390 | break; |
diff --git a/shell/hush.c b/shell/hush.c index da0db7948..23e7f512f 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -2941,12 +2941,9 @@ static void i_prepend_to_alias_buffer(struct in_str *i, char *prepend, char ch) | |||
| 2941 | * a | 2941 | * a |
| 2942 | * ^^^ runs "echo A: c" | 2942 | * ^^^ runs "echo A: c" |
| 2943 | */ | 2943 | */ |
| 2944 | char *old = i->albuf; | ||
| 2945 | //bb_error_msg("before'%s' p'%s'", i->albuf, i->p); | 2944 | //bb_error_msg("before'%s' p'%s'", i->albuf, i->p); |
| 2946 | i->albuf = xasprintf("%s%c%s", prepend, ch, i->p); | 2945 | i->p = xasprintf_inplace(i->albuf, "%s%c%s", prepend, ch, i->p); |
| 2947 | i->p = i->albuf; | ||
| 2948 | //bb_error_msg("after'%s' p'%s'", i->albuf, i->p); | 2946 | //bb_error_msg("after'%s' p'%s'", i->albuf, i->p); |
| 2949 | free(old); | ||
| 2950 | return; | 2947 | return; |
| 2951 | } | 2948 | } |
| 2952 | i->saved_ibuf = i->p; | 2949 | i->saved_ibuf = i->p; |
diff --git a/util-linux/acpid.c b/util-linux/acpid.c index 5c0bb1768..386b988d2 100644 --- a/util-linux/acpid.c +++ b/util-linux/acpid.c | |||
| @@ -145,7 +145,7 @@ struct globals { | |||
| 145 | static void process_event(const char *event) | 145 | static void process_event(const char *event) |
| 146 | { | 146 | { |
| 147 | struct stat st; | 147 | struct stat st; |
| 148 | char *handler = xasprintf("./%s", event); | 148 | char *handler = concat_path_file(".", event); |
| 149 | const char *args[] = { "run-parts", handler, NULL }; | 149 | const char *args[] = { "run-parts", handler, NULL }; |
| 150 | 150 | ||
| 151 | // log the event | 151 | // log the event |
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c index 5d8f01a64..39eecc345 100644 --- a/util-linux/dmesg.c +++ b/util-linux/dmesg.c | |||
| @@ -91,7 +91,6 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) | |||
| 91 | if (len == 0) | 91 | if (len == 0) |
| 92 | return EXIT_SUCCESS; | 92 | return EXIT_SUCCESS; |
| 93 | 93 | ||
| 94 | |||
| 95 | if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) { | 94 | if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) { |
| 96 | int last = '\n'; | 95 | int last = '\n'; |
| 97 | int in = 0; | 96 | int in = 0; |
diff --git a/util-linux/lsblk.c b/util-linux/lsblk.c index a482bfbbc..3bd40bcb4 100644 --- a/util-linux/lsblk.c +++ b/util-linux/lsblk.c | |||
| @@ -101,10 +101,10 @@ static char *get_mountpoints(const char *majmin) | |||
| 101 | 101 | ||
| 102 | mountpoints = NULL; | 102 | mountpoints = NULL; |
| 103 | len = strlen(majmin); | 103 | len = strlen(majmin); |
| 104 | p = G.mountinfo; // "/proc/self/mountinfo" | 104 | p = G.mountinfo; // contents of "/proc/self/mountinfo" |
| 105 | /* lines a-la "63 1 259:3 / /MNTPOINT per-mount_options - ext4 /dev/NAME per-superblock_options" */ | 105 | /* lines a-la "63 1 259:3 / /MNTPOINT per-mount_options - ext4 /dev/NAME per-superblock_options" */ |
| 106 | while (*p) { | 106 | while (*p) { |
| 107 | char *e, *f; | 107 | char *e; |
| 108 | 108 | ||
| 109 | p = skip_non_whitespace(p); | 109 | p = skip_non_whitespace(p); |
| 110 | if (*p != ' ') break; | 110 | if (*p != ' ') break; |
| @@ -127,12 +127,11 @@ static char *get_mountpoints(const char *majmin) | |||
| 127 | // at " /MNTPOINT" | 127 | // at " /MNTPOINT" |
| 128 | e = skip_non_whitespace(p + 1); | 128 | e = skip_non_whitespace(p + 1); |
| 129 | // e is at the end of " /MNTPOINT" | 129 | // e is at the end of " /MNTPOINT" |
| 130 | f = mountpoints; | ||
| 131 | // NO. We return " /MNT1 /MNT2 /MNT3" _with_ leading space! | 130 | // NO. We return " /MNT1 /MNT2 /MNT3" _with_ leading space! |
| 132 | // if (!f) | 131 | // if (!mountpoints) |
| 133 | // p++; | 132 | // p++; |
| 134 | mountpoints = xasprintf("%s%.*s", f ? f : "", (int)(e - p), p); | 133 | xasprintf_inplace(mountpoints, "%s%.*s", |
| 135 | free(f); | 134 | mountpoints ? mountpoints : "", (int)(e - p), p); |
| 136 | } | 135 | } |
| 137 | return mountpoints; | 136 | return mountpoints; |
| 138 | } | 137 | } |
diff --git a/util-linux/lspci.c b/util-linux/lspci.c index 25be23a01..1a43f71e2 100644 --- a/util-linux/lspci.c +++ b/util-linux/lspci.c | |||
| @@ -81,7 +81,6 @@ static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM, | |||
| 81 | } | 81 | } |
| 82 | config_close(parser); | 82 | config_close(parser); |
| 83 | 83 | ||
| 84 | |||
| 85 | if (option_mask32 & OPT_m) { | 84 | if (option_mask32 & OPT_m) { |
| 86 | printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"", | 85 | printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"", |
| 87 | pci_slot_name, pci_class, pci_vid, pci_did, | 86 | pci_slot_name, pci_class, pci_vid, pci_did, |
diff --git a/util-linux/mount.c b/util-linux/mount.c index d0f0ae1ad..d0d109c09 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
| @@ -556,27 +556,33 @@ static int verbose_mount(const char *source, const char *target, | |||
| 556 | #endif | 556 | #endif |
| 557 | 557 | ||
| 558 | // Append mount options to string | 558 | // Append mount options to string |
| 559 | // ("merge two comma-separated lists" is a good candidate for libbb!) | ||
| 559 | static void append_mount_options(char **oldopts, const char *newopts) | 560 | static void append_mount_options(char **oldopts, const char *newopts) |
| 560 | { | 561 | { |
| 561 | if (*oldopts && **oldopts) { | 562 | if (*oldopts && **oldopts) { |
| 563 | //TODO: do this unconditionally? | ||
| 564 | //this way, newopts of "opt1,opt2,opt1" | ||
| 565 | //will be de-duped into "opt1,opt2" in _both_ cases | ||
| 566 | //(whether or now old opts are empty) | ||
| 567 | //the only modification needed is to not prepend extra comma | ||
| 568 | //when old opts is "". | ||
| 562 | // Do not insert options which are already there | 569 | // Do not insert options which are already there |
| 563 | while (newopts[0]) { | 570 | while (*newopts) { |
| 564 | char *p; | 571 | char *p; |
| 565 | int len; | 572 | int len; |
| 566 | 573 | ||
| 574 | //if (*newopts == ',') { newopts++; continue; } | ||
| 567 | len = strchrnul(newopts, ',') - newopts; | 575 | len = strchrnul(newopts, ',') - newopts; |
| 568 | p = *oldopts; | 576 | p = *oldopts; |
| 569 | while (1) { | 577 | while (1) { |
| 570 | if (!strncmp(p, newopts, len) | 578 | if (strncmp(p, newopts, len) == 0 |
| 571 | && (p[len] == ',' || p[len] == '\0')) | 579 | && (p[len] == ',' || p[len] == '\0')) |
| 572 | goto skip; | 580 | goto skip; |
| 573 | p = strchr(p,','); | 581 | p = strchr(p, ','); |
| 574 | if (!p) break; | 582 | if (!p) break; |
| 575 | p++; | 583 | p++; |
| 576 | } | 584 | } |
| 577 | p = xasprintf("%s,%.*s", *oldopts, len, newopts); | 585 | xasprintf_inplace(*oldopts, "%s,%.*s", *oldopts, len, newopts); |
| 578 | free(*oldopts); | ||
| 579 | *oldopts = p; | ||
| 580 | skip: | 586 | skip: |
| 581 | newopts += len; | 587 | newopts += len; |
| 582 | while (*newopts == ',') newopts++; | 588 | while (*newopts == ',') newopts++; |
| @@ -2065,12 +2071,11 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
| 2065 | if (!is_prefixed_with(filteropts, ",ip="+1) | 2071 | if (!is_prefixed_with(filteropts, ",ip="+1) |
| 2066 | && !strstr(filteropts, ",ip=") | 2072 | && !strstr(filteropts, ",ip=") |
| 2067 | ) { | 2073 | ) { |
| 2068 | char *dotted, *ip; | 2074 | char *ip; |
| 2069 | // Insert "ip=..." option into options | 2075 | // Insert "ip=..." option into options |
| 2070 | dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | 2076 | ip = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); |
| 2071 | if (ENABLE_FEATURE_CLEAN_UP) free(lsa); | 2077 | if (ENABLE_FEATURE_CLEAN_UP) free(lsa); |
| 2072 | ip = xasprintf("ip=%s", dotted); | 2078 | xasprintf_inplace(ip, "ip=%s", ip); |
| 2073 | if (ENABLE_FEATURE_CLEAN_UP) free(dotted); | ||
| 2074 | // Note: IPv6 scoped addresses ("host%iface", see RFC 4007) should be | 2079 | // Note: IPv6 scoped addresses ("host%iface", see RFC 4007) should be |
| 2075 | // handled by libc in getnameinfo() (inside xmalloc_sockaddr2dotted_noport()). | 2080 | // handled by libc in getnameinfo() (inside xmalloc_sockaddr2dotted_noport()). |
| 2076 | // Currently, glibc does not support that (has no NI_NUMERICSCOPE), | 2081 | // Currently, glibc does not support that (has no NI_NUMERICSCOPE), |
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c index 39155f256..52bb8e03a 100644 --- a/util-linux/volume_id/get_devname.c +++ b/util-linux/volume_id/get_devname.c | |||
| @@ -110,7 +110,7 @@ uuidcache_check_device(struct recursive_state *state UNUSED_PARAM, | |||
| 110 | /* note: this check rejects links to devices, among other nodes */ | 110 | /* note: this check rejects links to devices, among other nodes */ |
| 111 | if (!S_ISBLK(statbuf->st_mode) | 111 | if (!S_ISBLK(statbuf->st_mode) |
| 112 | #if ENABLE_FEATURE_VOLUMEID_UBIFS | 112 | #if ENABLE_FEATURE_VOLUMEID_UBIFS |
| 113 | && !(S_ISCHR(statbuf->st_mode) && strncmp(bb_basename(device), "ubi", 3) == 0) | 113 | && !(S_ISCHR(statbuf->st_mode) && is_prefixed_with(bb_basename(device), "ubi")) |
| 114 | #endif | 114 | #endif |
| 115 | ) | 115 | ) |
| 116 | return TRUE; | 116 | return TRUE; |
diff --git a/util-linux/volume_id/unused_lvm.c b/util-linux/volume_id/unused_lvm.c index 649306c85..512aa7962 100644 --- a/util-linux/volume_id/unused_lvm.c +++ b/util-linux/volume_id/unused_lvm.c | |||
| @@ -74,7 +74,6 @@ int FAST_FUNC volume_id_probe_lvm2(struct volume_id *id, uint64_t off) | |||
| 74 | if (buf == NULL) | 74 | if (buf == NULL) |
| 75 | return -1; | 75 | return -1; |
| 76 | 76 | ||
| 77 | |||
| 78 | for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { | 77 | for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { |
| 79 | lvm = (struct lvm2_super_block *) &buf[soff]; | 78 | lvm = (struct lvm2_super_block *) &buf[soff]; |
| 80 | 79 | ||
