diff options
Diffstat (limited to 'networking/ifupdown.c')
| -rw-r--r-- | networking/ifupdown.c | 124 |
1 files changed, 65 insertions, 59 deletions
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 6d608105e..7a9709e40 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
| @@ -87,23 +87,29 @@ struct interfaces_file_t { | |||
| 87 | struct mapping_defn_t *mappings; | 87 | struct mapping_defn_t *mappings; |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | |||
| 90 | #define OPTION_STR "anvf" IF_FEATURE_IFUPDOWN_MAPPING("m") "i:" | 91 | #define OPTION_STR "anvf" IF_FEATURE_IFUPDOWN_MAPPING("m") "i:" |
| 91 | enum { | 92 | enum { |
| 92 | OPT_do_all = 0x1, | 93 | OPT_do_all = 0x1, |
| 93 | OPT_no_act = 0x2, | 94 | OPT_no_act = 0x2, |
| 94 | OPT_verbose = 0x4, | 95 | OPT_verbose = 0x4, |
| 95 | OPT_force = 0x8, | 96 | OPT_force = 0x8, |
| 96 | OPT_no_mappings = 0x10, | 97 | OPT_no_mappings = 0x10, |
| 97 | }; | 98 | }; |
| 98 | #define DO_ALL (option_mask32 & OPT_do_all) | 99 | #define DO_ALL (option_mask32 & OPT_do_all) |
| 99 | #define NO_ACT (option_mask32 & OPT_no_act) | 100 | #define NO_ACT (option_mask32 & OPT_no_act) |
| 100 | #define VERBOSE (option_mask32 & OPT_verbose) | 101 | #define VERBOSE (option_mask32 & OPT_verbose) |
| 101 | #define FORCE (option_mask32 & OPT_force) | 102 | #define FORCE (option_mask32 & OPT_force) |
| 102 | #define NO_MAPPINGS (option_mask32 & OPT_no_mappings) | 103 | #define NO_MAPPINGS (option_mask32 & OPT_no_mappings) |
| 103 | 104 | ||
| 104 | static char **my_environ; | ||
| 105 | 105 | ||
| 106 | static const char *startup_PATH; | 106 | struct globals { |
| 107 | char **my_environ; | ||
| 108 | const char *startup_PATH; | ||
| 109 | }; | ||
| 110 | #define G (*(struct globals*)&bb_common_bufsiz1) | ||
| 111 | #define INIT_G() do { } while (0) | ||
| 112 | |||
| 107 | 113 | ||
| 108 | #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 | 114 | #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 |
| 109 | 115 | ||
| @@ -126,7 +132,7 @@ static int strncmpz(const char *l, const char *r, size_t llen) | |||
| 126 | int i = strncmp(l, r, llen); | 132 | int i = strncmp(l, r, llen); |
| 127 | 133 | ||
| 128 | if (i == 0) | 134 | if (i == 0) |
| 129 | return -r[llen]; | 135 | return - (unsigned char)r[llen]; |
| 130 | return i; | 136 | return i; |
| 131 | } | 137 | } |
| 132 | 138 | ||
| @@ -135,16 +141,17 @@ static char *get_var(const char *id, size_t idlen, struct interface_defn_t *ifd) | |||
| 135 | int i; | 141 | int i; |
| 136 | 142 | ||
| 137 | if (strncmpz(id, "iface", idlen) == 0) { | 143 | if (strncmpz(id, "iface", idlen) == 0) { |
| 138 | static char *label_buf; | 144 | // ubuntu's ifup doesn't do this: |
| 145 | //static char *label_buf; | ||
| 139 | //char *result; | 146 | //char *result; |
| 140 | 147 | //free(label_buf); | |
| 141 | free(label_buf); | 148 | //label_buf = xstrdup(ifd->iface); |
| 142 | label_buf = xstrdup(ifd->iface); | 149 | // Remove virtual iface suffix |
| 143 | // Remove virtual iface suffix - why? | ||
| 144 | // ubuntu's ifup doesn't do this | ||
| 145 | //result = strchrnul(label_buf, ':'); | 150 | //result = strchrnul(label_buf, ':'); |
| 146 | //*result = '\0'; | 151 | //*result = '\0'; |
| 147 | return label_buf; | 152 | //return label_buf; |
| 153 | |||
| 154 | return ifd->iface; | ||
| 148 | } | 155 | } |
| 149 | if (strncmpz(id, "label", idlen) == 0) { | 156 | if (strncmpz(id, "label", idlen) == 0) { |
| 150 | return ifd->iface; | 157 | return ifd->iface; |
| @@ -547,7 +554,7 @@ static int FAST_FUNC dhcp_down(struct interface_defn_t *ifd, execfn *exec) | |||
| 547 | 554 | ||
| 548 | for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { | 555 | for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { |
| 549 | if (exists_execable(ext_dhcp_clients[i].name)) { | 556 | if (exists_execable(ext_dhcp_clients[i].name)) { |
| 550 | result += execute(ext_dhcp_clients[i].stopcmd, ifd, exec); | 557 | result = execute(ext_dhcp_clients[i].stopcmd, ifd, exec); |
| 551 | if (result) | 558 | if (result) |
| 552 | break; | 559 | break; |
| 553 | } | 560 | } |
| @@ -620,13 +627,13 @@ static int FAST_FUNC wvdial_down(struct interface_defn_t *ifd, execfn *exec) | |||
| 620 | } | 627 | } |
| 621 | 628 | ||
| 622 | static const struct method_t methods[] = { | 629 | static const struct method_t methods[] = { |
| 623 | { "manual", manual_up_down, manual_up_down, }, | 630 | { "manual" , manual_up_down, manual_up_down, }, |
| 624 | { "wvdial", wvdial_up, wvdial_down, }, | 631 | { "wvdial" , wvdial_up , wvdial_down , }, |
| 625 | { "ppp", ppp_up, ppp_down, }, | 632 | { "ppp" , ppp_up , ppp_down , }, |
| 626 | { "static", static_up, static_down, }, | 633 | { "static" , static_up , static_down , }, |
| 627 | { "bootp", bootp_up, static_down, }, | 634 | { "bootp" , bootp_up , static_down , }, |
| 628 | { "dhcp", dhcp_up, dhcp_down, }, | 635 | { "dhcp" , dhcp_up , dhcp_down , }, |
| 629 | { "loopback", loopback_up, loopback_down, }, | 636 | { "loopback", loopback_up , loopback_down , }, |
| 630 | }; | 637 | }; |
| 631 | 638 | ||
| 632 | static const struct address_family_t addr_inet = { | 639 | static const struct address_family_t addr_inet = { |
| @@ -896,43 +903,40 @@ static struct interfaces_file_t *read_interfaces(const char *filename) | |||
| 896 | static char *setlocalenv(const char *format, const char *name, const char *value) | 903 | static char *setlocalenv(const char *format, const char *name, const char *value) |
| 897 | { | 904 | { |
| 898 | char *result; | 905 | char *result; |
| 899 | char *here; | 906 | char *dst; |
| 900 | char *there; | 907 | char *src; |
| 908 | char c; | ||
| 901 | 909 | ||
| 902 | result = xasprintf(format, name, value); | 910 | result = xasprintf(format, name, value); |
| 903 | 911 | ||
| 904 | for (here = there = result; *there != '=' && *there; there++) { | 912 | for (dst = src = result; (c = *src) != '=' && c; src++) { |
| 905 | if (*there == '-') | 913 | if (c == '-') |
| 906 | *there = '_'; | 914 | c = '_'; |
| 907 | if (isalpha(*there)) | 915 | if (c >= 'a' && c <= 'z') |
| 908 | *there = toupper(*there); | 916 | c -= ('a' - 'A'); |
| 909 | 917 | if (isalnum(c) || c == '_') | |
| 910 | if (isalnum(*there) || *there == '_') { | 918 | *dst++ = c; |
| 911 | *here = *there; | ||
| 912 | here++; | ||
| 913 | } | ||
| 914 | } | 919 | } |
| 915 | memmove(here, there, strlen(there) + 1); | 920 | overlapping_strcpy(dst, src); |
| 916 | 921 | ||
| 917 | return result; | 922 | return result; |
| 918 | } | 923 | } |
| 919 | 924 | ||
| 920 | static void set_environ(struct interface_defn_t *iface, const char *mode) | 925 | static void set_environ(struct interface_defn_t *iface, const char *mode) |
| 921 | { | 926 | { |
| 922 | char **environend; | ||
| 923 | int i; | 927 | int i; |
| 924 | const int n_env_entries = iface->n_options + 5; | 928 | char **pp; |
| 925 | char **ppch; | ||
| 926 | 929 | ||
| 927 | if (my_environ != NULL) { | 930 | if (G.my_environ != NULL) { |
| 928 | for (ppch = my_environ; *ppch; ppch++) { | 931 | for (pp = G.my_environ; *pp; pp++) { |
| 929 | free(*ppch); | 932 | free(*pp); |
| 930 | *ppch = NULL; | ||
| 931 | } | 933 | } |
| 932 | free(my_environ); | 934 | free(G.my_environ); |
| 933 | } | 935 | } |
| 934 | my_environ = xzalloc(sizeof(char *) * (n_env_entries + 1 /* for final NULL */ )); | 936 | |
| 935 | environend = my_environ; | 937 | /* note: last element will stay NULL: */ |
| 938 | G.my_environ = xzalloc(sizeof(char *) * (iface->n_options + 6)); | ||
| 939 | pp = G.my_environ; | ||
| 936 | 940 | ||
| 937 | for (i = 0; i < iface->n_options; i++) { | 941 | for (i = 0; i < iface->n_options; i++) { |
| 938 | if (strcmp(iface->option[i].name, "up") == 0 | 942 | if (strcmp(iface->option[i].name, "up") == 0 |
| @@ -942,14 +946,15 @@ static void set_environ(struct interface_defn_t *iface, const char *mode) | |||
| 942 | ) { | 946 | ) { |
| 943 | continue; | 947 | continue; |
| 944 | } | 948 | } |
| 945 | *(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); | 949 | *pp++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); |
| 946 | } | 950 | } |
| 947 | 951 | ||
| 948 | *(environend++) = setlocalenv("%s=%s", "IFACE", iface->iface); | 952 | *pp++ = setlocalenv("%s=%s", "IFACE", iface->iface); |
| 949 | *(environend++) = setlocalenv("%s=%s", "ADDRFAM", iface->address_family->name); | 953 | *pp++ = setlocalenv("%s=%s", "ADDRFAM", iface->address_family->name); |
| 950 | *(environend++) = setlocalenv("%s=%s", "METHOD", iface->method->name); | 954 | *pp++ = setlocalenv("%s=%s", "METHOD", iface->method->name); |
| 951 | *(environend++) = setlocalenv("%s=%s", "MODE", mode); | 955 | *pp++ = setlocalenv("%s=%s", "MODE", mode); |
| 952 | *(environend++) = setlocalenv("%s=%s", "PATH", startup_PATH); | 956 | if (G.startup_PATH) |
| 957 | *pp++ = setlocalenv("%s=%s", "PATH", G.startup_PATH); | ||
| 953 | } | 958 | } |
| 954 | 959 | ||
| 955 | static int doit(char *str) | 960 | static int doit(char *str) |
| @@ -967,7 +972,7 @@ static int doit(char *str) | |||
| 967 | case -1: /* failure */ | 972 | case -1: /* failure */ |
| 968 | return 0; | 973 | return 0; |
| 969 | case 0: /* child */ | 974 | case 0: /* child */ |
| 970 | execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, (char *) NULL, my_environ); | 975 | execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, (char *) NULL, G.my_environ); |
| 971 | _exit(127); | 976 | _exit(127); |
| 972 | } | 977 | } |
| 973 | safe_waitpid(child, &status, 0); | 978 | safe_waitpid(child, &status, 0); |
| @@ -1142,6 +1147,10 @@ int ifupdown_main(int argc, char **argv) | |||
| 1142 | const char *interfaces = "/etc/network/interfaces"; | 1147 | const char *interfaces = "/etc/network/interfaces"; |
| 1143 | bool any_failures = 0; | 1148 | bool any_failures = 0; |
| 1144 | 1149 | ||
| 1150 | INIT_G(); | ||
| 1151 | |||
| 1152 | G.startup_PATH = getenv("PATH"); | ||
| 1153 | |||
| 1145 | cmds = iface_down; | 1154 | cmds = iface_down; |
| 1146 | if (applet_name[2] == 'u') { | 1155 | if (applet_name[2] == 'u') { |
| 1147 | /* ifup command */ | 1156 | /* ifup command */ |
| @@ -1159,9 +1168,6 @@ int ifupdown_main(int argc, char **argv) | |||
| 1159 | defn = read_interfaces(interfaces); | 1168 | defn = read_interfaces(interfaces); |
| 1160 | debug_noise("\ndone reading %s\n\n", interfaces); | 1169 | debug_noise("\ndone reading %s\n\n", interfaces); |
| 1161 | 1170 | ||
| 1162 | startup_PATH = getenv("PATH"); | ||
| 1163 | if (!startup_PATH) startup_PATH = ""; | ||
| 1164 | |||
| 1165 | /* Create a list of interfaces to work on */ | 1171 | /* Create a list of interfaces to work on */ |
| 1166 | if (DO_ALL) { | 1172 | if (DO_ALL) { |
| 1167 | target_list = defn->autointerfaces; | 1173 | target_list = defn->autointerfaces; |
