httpd: make byte ranges which start at 0 work too. Closes 4766
[oweals/busybox.git] / networking / ifupdown.c
index 7706a84b7e1134bec09b58f88ead0b513cf75819..73da26085c4058ba51cca1690f3c625f816a16ef 100644 (file)
  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
 
+//usage:#define ifup_trivial_usage
+//usage:       "[-an"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] [-i FILE] IFACE..."
+//usage:#define ifup_full_usage "\n\n"
+//usage:       "       -a      De/configure all interfaces automatically"
+//usage:     "\n       -i FILE Use FILE for interface definitions"
+//usage:     "\n       -n      Print out what would happen, but don't do it"
+//usage:       IF_FEATURE_IFUPDOWN_MAPPING(
+//usage:     "\n               (note: doesn't disable mappings)"
+//usage:     "\n       -m      Don't run any mappings"
+//usage:       )
+//usage:     "\n       -v      Print out what would happen before doing it"
+//usage:     "\n       -f      Force de/configuration"
+//usage:
+//usage:#define ifdown_trivial_usage
+//usage:       "[-an"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] [-i FILE] IFACE..."
+//usage:#define ifdown_full_usage "\n\n"
+//usage:       "       -a      De/configure all interfaces automatically"
+//usage:     "\n       -i FILE Use FILE for interface definitions"
+//usage:     "\n       -n      Print out what would happen, but don't do it"
+//usage:       IF_FEATURE_IFUPDOWN_MAPPING(
+//usage:     "\n               (note: doesn't disable mappings)"
+//usage:     "\n       -m      Don't run any mappings"
+//usage:       )
+//usage:     "\n       -v      Print out what would happen before doing it"
+//usage:     "\n       -f      Force de/configuration"
+
 #include "libbb.h"
 /* After libbb.h, since it needs sys/types.h on some systems */
 #include <sys/utsname.h>
@@ -61,7 +87,6 @@ struct mapping_defn_t {
 
        char *script;
 
-       int max_mappings;
        int n_mappings;
        char **mapping;
 };
@@ -76,7 +101,6 @@ struct interface_defn_t {
        const struct method_t *method;
 
        char *iface;
-       int max_options;
        int n_options;
        struct variable_t *option;
 };
@@ -112,6 +136,16 @@ struct globals {
 #define INIT_G() do { } while (0)
 
 
+static const char keywords_up_down[] ALIGN1 =
+       "up\0"
+       "down\0"
+       "pre-up\0"
+       "pre-down\0"
+       "post-up\0"
+       "post-down\0"
+;
+
+
 #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6
 
 static void addstr(char **bufp, const char *str, size_t str_length)
@@ -777,7 +811,6 @@ static struct interfaces_file_t *read_interfaces(const char *filename)
                                currmap->match = xrealloc_vector(currmap->match, 4, currmap->n_matches);
                                currmap->match[currmap->n_matches++] = xstrdup(first_word);
                        }
-                       /*currmap->max_mappings = 0; - done by xzalloc */
                        /*currmap->n_mappings = 0;*/
                        /*currmap->mapping = NULL;*/
                        /*currmap->script = NULL;*/
@@ -862,23 +895,16 @@ static struct interfaces_file_t *read_interfaces(const char *filename)
                                if (rest_of_line[0] == '\0')
                                        bb_error_msg_and_die("option with empty value \"%s\"", buf);
 
-                               if (strcmp(first_word, "up") != 0
-                                && strcmp(first_word, "down") != 0
-                                && strcmp(first_word, "pre-up") != 0
-                                && strcmp(first_word, "post-down") != 0
-                               ) {
+                               /* If not one of "up", "down",... words... */
+                               if (index_in_strings(keywords_up_down, first_word) < 0) {
                                        int i;
                                        for (i = 0; i < currif->n_options; i++) {
                                                if (strcmp(currif->option[i].name, first_word) == 0)
                                                        bb_error_msg_and_die("duplicate option \"%s\"", buf);
                                        }
                                }
-                               if (currif->n_options >= currif->max_options) {
-                                       currif->max_options += 10;
-                                       currif->option = xrealloc(currif->option,
-                                               sizeof(*currif->option) * currif->max_options);
-                               }
                                debug_noise("\t%s=%s\n", first_word, rest_of_line);
+                               currif->option = xrealloc_vector(currif->option, 4, currif->n_options);
                                currif->option[currif->n_options].name = xstrdup(first_word);
                                currif->option[currif->n_options].value = xstrdup(rest_of_line);
                                currif->n_options++;
@@ -890,11 +916,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename)
                                                bb_error_msg_and_die("duplicate script in mapping \"%s\"", buf);
                                        currmap->script = xstrdup(next_word(&rest_of_line));
                                } else if (strcmp(first_word, "map") == 0) {
-                                       if (currmap->n_mappings >= currmap->max_mappings) {
-                                               currmap->max_mappings = currmap->max_mappings * 2 + 1;
-                                               currmap->mapping = xrealloc(currmap->mapping,
-                                                       sizeof(char *) * currmap->max_mappings);
-                                       }
+                                       currmap->mapping = xrealloc_vector(currmap->mapping, 2, currmap->n_mappings);
                                        currmap->mapping[currmap->n_mappings] = xstrdup(next_word(&rest_of_line));
                                        currmap->n_mappings++;
                                } else {
@@ -958,11 +980,7 @@ static void set_environ(struct interface_defn_t *iface, const char *mode)
        pp = G.my_environ;
 
        for (i = 0; i < iface->n_options; i++) {
-               if (strcmp(iface->option[i].name, "up") == 0
-                || strcmp(iface->option[i].name, "down") == 0
-                || strcmp(iface->option[i].name, "pre-up") == 0
-                || strcmp(iface->option[i].name, "post-down") == 0
-               ) {
+               if (index_in_strings(keywords_up_down, iface->option[i].name) >= 0) {
                        continue;
                }
                *pp++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value);
@@ -1030,6 +1048,7 @@ static int iface_up(struct interface_defn_t *iface)
        if (!execute_all(iface, "pre-up")) return 0;
        if (!iface->method->up(iface, doit)) return 0;
        if (!execute_all(iface, "up")) return 0;
+       if (!execute_all(iface, "post-up")) return 0;
        return 1;
 }
 
@@ -1037,6 +1056,7 @@ static int iface_down(struct interface_defn_t *iface)
 {
        if (!iface->method->down(iface,check)) return -1;
        set_environ(iface, "stop");
+       if (!execute_all(iface, "pre-down")) return 0;
        if (!execute_all(iface, "down")) return 0;
        if (!iface->method->down(iface, doit)) return 0;
        if (!execute_all(iface, "post-down")) return 0;
@@ -1291,9 +1311,9 @@ int ifupdown_main(int argc UNUSED_PARAM, char **argv)
                        llist_t *state_list = read_iface_state();
                        llist_t *iface_state = find_iface_state(state_list, iface);
 
-                       if (cmds == iface_up) {
-                               char * const newiface = xasprintf("%s=%s", iface, liface);
-                               if (iface_state == NULL) {
+                       if (cmds == iface_up && !any_failures) {
+                               char *newiface = xasprintf("%s=%s", iface, liface);
+                               if (!iface_state) {
                                        llist_add_to_end(&state_list, newiface);
                                } else {
                                        free(iface_state->data);