summaryrefslogtreecommitdiff
path: root/networking/ifupdown.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-02 21:38:44 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-02 21:38:44 +0000
commitbd100b7478340a28fed272e60c87da37dab125e6 (patch)
tree05041aa120b7b2f7cb5534743f4fb7a509322517 /networking/ifupdown.c
parent4ac530c0ef4f2c4c15a177456b01e240bfb9f1aa (diff)
downloadbusybox-w32-bd100b7478340a28fed272e60c87da37dab125e6.tar.gz
busybox-w32-bd100b7478340a28fed272e60c87da37dab125e6.tar.bz2
busybox-w32-bd100b7478340a28fed272e60c87da37dab125e6.zip
ifupdown: reread state file before rewriting it.
Fixes "ifup started another ifup" state corruption bug. Patch by Natanael Copa <natanael.copa@gmail.com>.
Diffstat (limited to '')
-rw-r--r--networking/ifupdown.c73
1 files changed, 37 insertions, 36 deletions
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 887c2eea5..ff4f7855b 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -1083,15 +1083,33 @@ static llist_t *find_iface_state(llist_t *state_list, const char *iface)
1083 return NULL; 1083 return NULL;
1084} 1084}
1085 1085
1086/* read the previous state from the state file */
1087static llist_t *read_iface_state(void)
1088{
1089 llist_t *state_list = NULL;
1090 FILE *state_fp = fopen("/var/run/ifstate", "r");
1091
1092 if (state_fp) {
1093 char *start, *end_ptr;
1094 while ((start = xmalloc_fgets(state_fp)) != NULL) {
1095 /* We should only need to check for a single character */
1096 end_ptr = start + strcspn(start, " \t\n");
1097 *end_ptr = '\0';
1098 llist_add_to(&state_list, start);
1099 }
1100 fclose(state_fp);
1101 }
1102 return state_list;
1103}
1104
1105
1086int ifupdown_main(int argc, char **argv); 1106int ifupdown_main(int argc, char **argv);
1087int ifupdown_main(int argc, char **argv) 1107int ifupdown_main(int argc, char **argv)
1088{ 1108{
1089 int (*cmds)(struct interface_defn_t *) = NULL; 1109 int (*cmds)(struct interface_defn_t *) = NULL;
1090 struct interfaces_file_t *defn; 1110 struct interfaces_file_t *defn;
1091 llist_t *state_list = NULL;
1092 llist_t *target_list = NULL; 1111 llist_t *target_list = NULL;
1093 const char *interfaces = "/etc/network/interfaces"; 1112 const char *interfaces = "/etc/network/interfaces";
1094 FILE *state_fp;
1095 bool any_failures = 0; 1113 bool any_failures = 0;
1096 1114
1097 cmds = iface_down; 1115 cmds = iface_down;
@@ -1118,32 +1136,9 @@ int ifupdown_main(int argc, char **argv)
1118 startup_PATH = getenv("PATH"); 1136 startup_PATH = getenv("PATH");
1119 if (!startup_PATH) startup_PATH = ""; 1137 if (!startup_PATH) startup_PATH = "";
1120 1138
1121 /* Read the previous state from the state file */
1122 state_fp = fopen("/var/run/ifstate", "r");
1123 if (state_fp) {
1124 char *start, *end_ptr;
1125 while ((start = xmalloc_fgets(state_fp)) != NULL) {
1126 /* We should only need to check for a single character */
1127 end_ptr = start + strcspn(start, " \t\n");
1128 *end_ptr = '\0';
1129 llist_add_to(&state_list, start);
1130 }
1131 fclose(state_fp);
1132 }
1133
1134 /* Create a list of interfaces to work on */ 1139 /* Create a list of interfaces to work on */
1135 if (DO_ALL) { 1140 if (DO_ALL) {
1136 if (cmds == iface_up) { 1141 target_list = defn->autointerfaces;
1137 target_list = defn->autointerfaces;
1138 } else {
1139 /* iface_down */
1140 const llist_t *list = state_list;
1141 while (list) {
1142 llist_add_to_end(&target_list, xstrdup(list->data));
1143 list = list->link;
1144 }
1145 target_list = defn->autointerfaces;
1146 }
1147 } else { 1142 } else {
1148 llist_add_to_end(&target_list, argv[optind]); 1143 llist_add_to_end(&target_list, argv[optind]);
1149 } 1144 }
@@ -1170,6 +1165,7 @@ int ifupdown_main(int argc, char **argv)
1170 } 1165 }
1171 1166
1172 if (!FORCE) { 1167 if (!FORCE) {
1168 llist_t *state_list = read_iface_state();
1173 const llist_t *iface_state = find_iface_state(state_list, iface); 1169 const llist_t *iface_state = find_iface_state(state_list, iface);
1174 1170
1175 if (cmds == iface_up) { 1171 if (cmds == iface_up) {
@@ -1185,6 +1181,7 @@ int ifupdown_main(int argc, char **argv)
1185 continue; 1181 continue;
1186 } 1182 }
1187 } 1183 }
1184 llist_free(state_list, free);
1188 } 1185 }
1189 1186
1190#if ENABLE_FEATURE_IFUPDOWN_MAPPING 1187#if ENABLE_FEATURE_IFUPDOWN_MAPPING
@@ -1239,6 +1236,8 @@ int ifupdown_main(int argc, char **argv)
1239 bb_error_msg("ignoring unknown interface %s", liface); 1236 bb_error_msg("ignoring unknown interface %s", liface);
1240 any_failures = 1; 1237 any_failures = 1;
1241 } else { 1238 } else {
1239 /* update the state file */
1240 llist_t *state_list = read_iface_state();
1242 llist_t *iface_state = find_iface_state(state_list, iface); 1241 llist_t *iface_state = find_iface_state(state_list, iface);
1243 1242
1244 if (cmds == iface_up) { 1243 if (cmds == iface_up) {
@@ -1254,19 +1253,21 @@ int ifupdown_main(int argc, char **argv)
1254 llist_unlink(&state_list, iface_state); 1253 llist_unlink(&state_list, iface_state);
1255 free(llist_pop(&iface_state)); 1254 free(llist_pop(&iface_state));
1256 } 1255 }
1257 }
1258 }
1259 1256
1260 /* Actually write the new state */ 1257 /* Actually write the new state */
1261 if (!NO_ACT) { 1258 if (!NO_ACT) {
1262 state_fp = xfopen("/var/run/ifstate", "w"); 1259 FILE *state_fp = xfopen("/var/run/ifstate", "w");
1263 while (state_list) { 1260 llist_t *state = state_list;
1264 if (state_list->data) { 1261 while (state) {
1265 fprintf(state_fp, "%s\n", state_list->data); 1262 if (state->data) {
1263 fprintf(state_fp, "%s\n", state->data);
1264 }
1265 state = state->link;
1266 }
1267 fclose(state_fp);
1266 } 1268 }
1267 state_list = state_list->link; 1269 llist_free(state_list, free);
1268 } 1270 }
1269 fclose(state_fp);
1270 } 1271 }
1271 1272
1272 return any_failures; 1273 return any_failures;