aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-03-06 22:53:10 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-03-06 22:53:10 +0000
commitca263b0920eb8c2a4fd4ebf24939894c85a075f6 (patch)
tree7d389439583b48b42692f10b121ffd4e7b24aa76
parent12a403bcb5e2a400300ae856b6fcdb0f1fc324f5 (diff)
downloadbusybox-w32-ca263b0920eb8c2a4fd4ebf24939894c85a075f6.tar.gz
busybox-w32-ca263b0920eb8c2a4fd4ebf24939894c85a075f6.tar.bz2
busybox-w32-ca263b0920eb8c2a4fd4ebf24939894c85a075f6.zip
ifupdown: code to deconstruct the state_list gracefully
(patch by Gabriel L. Somlo <somlo@cmu.edu>) git-svn-id: svn://busybox.net/trunk/busybox@18018 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/llist.c35
-rw-r--r--networking/ifupdown.c21
3 files changed, 45 insertions, 12 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 4293ae269..809d8446a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -475,6 +475,7 @@ typedef struct llist_s {
475extern void llist_add_to(llist_t **old_head, void *data); 475extern void llist_add_to(llist_t **old_head, void *data);
476extern void llist_add_to_end(llist_t **list_head, void *data); 476extern void llist_add_to_end(llist_t **list_head, void *data);
477extern void *llist_pop(llist_t **elm); 477extern void *llist_pop(llist_t **elm);
478extern void llist_unlink(llist_t **head, llist_t *elm);
478extern void llist_free(llist_t *elm, void (*freeit)(void *data)); 479extern void llist_free(llist_t *elm, void (*freeit)(void *data));
479extern llist_t* llist_rev(llist_t *list); 480extern llist_t* llist_rev(llist_t *list);
480 481
diff --git a/libbb/llist.c b/libbb/llist.c
index 0a5978a26..2b34f762c 100644
--- a/libbb/llist.c
+++ b/libbb/llist.c
@@ -45,21 +45,40 @@ void llist_add_to_end(llist_t ** list_head, void *data)
45/* Remove first element from the list and return it */ 45/* Remove first element from the list and return it */
46void *llist_pop(llist_t ** head) 46void *llist_pop(llist_t ** head)
47{ 47{
48 void *data; 48 void *data, *next;
49 49
50 if (!*head) 50 if (!*head)
51 data = *head; 51 return NULL;
52 else {
53 void *next = (*head)->link;
54 52
55 data = (*head)->data; 53 data = (*head)->data;
56 free(*head); 54 next = (*head)->link;
57 *head = next; 55 free(*head);
58 } 56 *head = next;
59 57
60 return data; 58 return data;
61} 59}
62 60
61/* Unlink arbitrary given element from the list */
62void llist_unlink(llist_t **head, llist_t *elm)
63{
64 llist_t *crt;
65
66 if (!(elm && *head))
67 return;
68
69 if (elm == *head) {
70 *head = (*head)->link;
71 return;
72 }
73
74 for (crt = *head; crt; crt = crt->link) {
75 if (crt->link == elm) {
76 crt->link = elm->link;
77 return;
78 }
79 }
80}
81
63/* Recursively free all elements in the linked list. If freeit != NULL 82/* Recursively free all elements in the linked list. If freeit != NULL
64 * call it on each datum in the list */ 83 * call it on each datum in the list */
65void llist_free(llist_t * elm, void (*freeit) (void *data)) 84void llist_free(llist_t * elm, void (*freeit) (void *data))
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index ccebecd95..c7cb85350 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -1091,6 +1091,7 @@ int ifupdown_main(int argc, char **argv)
1091 llist_t *state_list = NULL; 1091 llist_t *state_list = NULL;
1092 llist_t *target_list = NULL; 1092 llist_t *target_list = NULL;
1093 const char *interfaces = "/etc/network/interfaces"; 1093 const char *interfaces = "/etc/network/interfaces";
1094 FILE *state_fp;
1094 int any_failures = 0; 1095 int any_failures = 0;
1095 1096
1096 cmds = iface_down; 1097 cmds = iface_down;
@@ -1117,6 +1118,19 @@ int ifupdown_main(int argc, char **argv)
1117 startup_PATH = getenv("PATH"); 1118 startup_PATH = getenv("PATH");
1118 if (!startup_PATH) startup_PATH = ""; 1119 if (!startup_PATH) startup_PATH = "";
1119 1120
1121 /* Read the previous state from the state file */
1122 state_fp = fopen_or_warn("/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
1120 /* Create a list of interfaces to work on */ 1134 /* Create a list of interfaces to work on */
1121 if (DO_ALL) { 1135 if (DO_ALL) {
1122 if (cmds == iface_up) { 1136 if (cmds == iface_up) {
@@ -1166,7 +1180,7 @@ int ifupdown_main(int argc, char **argv)
1166 } 1180 }
1167 } else { 1181 } else {
1168 /* ifdown */ 1182 /* ifdown */
1169 if (iface_state) { 1183 if (!iface_state) {
1170 bb_error_msg("interface %s not configured", iface); 1184 bb_error_msg("interface %s not configured", iface);
1171 continue; 1185 continue;
1172 } 1186 }
@@ -1236,7 +1250,8 @@ int ifupdown_main(int argc, char **argv)
1236 iface_state->data = newiface; 1250 iface_state->data = newiface;
1237 } 1251 }
1238 } else { 1252 } else {
1239 /* Remove an interface from the linked list */ 1253 /* Remove an interface from state_list */
1254 llist_unlink(&state_list, iface_state);
1240 free(llist_pop(&iface_state)); 1255 free(llist_pop(&iface_state));
1241 } 1256 }
1242 } 1257 }
@@ -1244,8 +1259,6 @@ int ifupdown_main(int argc, char **argv)
1244 1259
1245 /* Actually write the new state */ 1260 /* Actually write the new state */
1246 if (!NO_ACT) { 1261 if (!NO_ACT) {
1247 FILE *state_fp;
1248
1249 state_fp = xfopen("/var/run/ifstate", "w"); 1262 state_fp = xfopen("/var/run/ifstate", "w");
1250 while (state_list) { 1263 while (state_list) {
1251 if (state_list->data) { 1264 if (state_list->data) {