17 |
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
18 |
*/ |
*/ |
19 |
|
|
20 |
|
#include "libbb.h" |
21 |
|
/* After libbb.h, since it needs sys/types.h on some systems */ |
22 |
#include <sys/utsname.h> |
#include <sys/utsname.h> |
23 |
#include <fnmatch.h> |
#include <fnmatch.h> |
24 |
|
|
|
#include "libbb.h" |
|
|
|
|
25 |
#define MAX_OPT_DEPTH 10 |
#define MAX_OPT_DEPTH 10 |
26 |
#define EUNBALBRACK 10001 |
#define EUNBALBRACK 10001 |
27 |
#define EUNDEFVAR 10002 |
#define EUNDEFVAR 10002 |
31 |
#define MAX_INTERFACE_LENGTH 10 |
#define MAX_INTERFACE_LENGTH 10 |
32 |
#endif |
#endif |
33 |
|
|
34 |
|
#define UDHCPC_CMD_OPTIONS CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS |
35 |
|
|
36 |
#define debug_noise(args...) /*fprintf(stderr, args)*/ |
#define debug_noise(args...) /*fprintf(stderr, args)*/ |
37 |
|
|
38 |
/* Forward declaration */ |
/* Forward declaration */ |
42 |
|
|
43 |
struct method_t { |
struct method_t { |
44 |
const char *name; |
const char *name; |
45 |
int (*up)(struct interface_defn_t *ifd, execfn *e); |
int (*up)(struct interface_defn_t *ifd, execfn *e) FAST_FUNC; |
46 |
int (*down)(struct interface_defn_t *ifd, execfn *e); |
int (*down)(struct interface_defn_t *ifd, execfn *e) FAST_FUNC; |
47 |
}; |
}; |
48 |
|
|
49 |
struct address_family_t { |
struct address_family_t { |
87 |
struct mapping_defn_t *mappings; |
struct mapping_defn_t *mappings; |
88 |
}; |
}; |
89 |
|
|
90 |
#define OPTION_STR "anvf" USE_FEATURE_IFUPDOWN_MAPPING("m") "i:" |
|
91 |
|
#define OPTION_STR "anvf" IF_FEATURE_IFUPDOWN_MAPPING("m") "i:" |
92 |
enum { |
enum { |
93 |
OPT_do_all = 0x1, |
OPT_do_all = 0x1, |
94 |
OPT_no_act = 0x2, |
OPT_no_act = 0x2, |
95 |
OPT_verbose = 0x4, |
OPT_verbose = 0x4, |
96 |
OPT_force = 0x8, |
OPT_force = 0x8, |
97 |
OPT_no_mappings = 0x10, |
OPT_no_mappings = 0x10, |
98 |
}; |
}; |
99 |
#define DO_ALL (option_mask32 & OPT_do_all) |
#define DO_ALL (option_mask32 & OPT_do_all) |
100 |
#define NO_ACT (option_mask32 & OPT_no_act) |
#define NO_ACT (option_mask32 & OPT_no_act) |
101 |
#define VERBOSE (option_mask32 & OPT_verbose) |
#define VERBOSE (option_mask32 & OPT_verbose) |
102 |
#define FORCE (option_mask32 & OPT_force) |
#define FORCE (option_mask32 & OPT_force) |
103 |
#define NO_MAPPINGS (option_mask32 & OPT_no_mappings) |
#define NO_MAPPINGS (option_mask32 & OPT_no_mappings) |
104 |
|
|
|
static char **my_environ; |
|
105 |
|
|
106 |
static const char *startup_PATH; |
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 |
|
|
113 |
|
|
114 |
#if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 |
#if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 |
115 |
|
|
132 |
int i = strncmp(l, r, llen); |
int i = strncmp(l, r, llen); |
133 |
|
|
134 |
if (i == 0) |
if (i == 0) |
135 |
return -r[llen]; |
return - (unsigned char)r[llen]; |
136 |
return i; |
return i; |
137 |
} |
} |
138 |
|
|
141 |
int i; |
int i; |
142 |
|
|
143 |
if (strncmpz(id, "iface", idlen) == 0) { |
if (strncmpz(id, "iface", idlen) == 0) { |
144 |
static char *label_buf; |
// ubuntu's ifup doesn't do this: |
145 |
|
//static char *label_buf; |
146 |
//char *result; |
//char *result; |
147 |
|
//free(label_buf); |
148 |
free(label_buf); |
//label_buf = xstrdup(ifd->iface); |
149 |
label_buf = xstrdup(ifd->iface); |
// Remove virtual iface suffix |
|
// Remove virtual iface suffix - why? |
|
|
// ubuntu's ifup doesn't do this |
|
150 |
//result = strchrnul(label_buf, ':'); |
//result = strchrnul(label_buf, ':'); |
151 |
//*result = '\0'; |
//*result = '\0'; |
152 |
return label_buf; |
//return label_buf; |
153 |
|
|
154 |
|
return ifd->iface; |
155 |
} |
} |
156 |
if (strncmpz(id, "label", idlen) == 0) { |
if (strncmpz(id, "label", idlen) == 0) { |
157 |
return ifd->iface; |
return ifd->iface; |
332 |
#endif |
#endif |
333 |
|
|
334 |
#if ENABLE_FEATURE_IFUPDOWN_IPV6 |
#if ENABLE_FEATURE_IFUPDOWN_IPV6 |
335 |
static int loopback_up6(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC loopback_up6(struct interface_defn_t *ifd, execfn *exec) |
336 |
{ |
{ |
337 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
338 |
int result; |
int result; |
344 |
#endif |
#endif |
345 |
} |
} |
346 |
|
|
347 |
static int loopback_down6(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC loopback_down6(struct interface_defn_t *ifd, execfn *exec) |
348 |
{ |
{ |
349 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
350 |
return execute("ip link set %iface% down", ifd, exec); |
return execute("ip link set %iface% down", ifd, exec); |
353 |
#endif |
#endif |
354 |
} |
} |
355 |
|
|
356 |
static int static_up6(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC static_up6(struct interface_defn_t *ifd, execfn *exec) |
357 |
{ |
{ |
358 |
int result; |
int result; |
359 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
369 |
return ((result == 3) ? 3 : 0); |
return ((result == 3) ? 3 : 0); |
370 |
} |
} |
371 |
|
|
372 |
static int static_down6(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC static_down6(struct interface_defn_t *ifd, execfn *exec) |
373 |
{ |
{ |
374 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
375 |
return execute("ip link set %iface% down", ifd, exec); |
return execute("ip link set %iface% down", ifd, exec); |
379 |
} |
} |
380 |
|
|
381 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
382 |
static int v4tunnel_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC v4tunnel_up(struct interface_defn_t *ifd, execfn *exec) |
383 |
{ |
{ |
384 |
int result; |
int result; |
385 |
result = execute("ip tunnel add %iface% mode sit remote " |
result = execute("ip tunnel add %iface% mode sit remote " |
390 |
return ((result == 4) ? 4 : 0); |
return ((result == 4) ? 4 : 0); |
391 |
} |
} |
392 |
|
|
393 |
static int v4tunnel_down(struct interface_defn_t * ifd, execfn * exec) |
static int FAST_FUNC v4tunnel_down(struct interface_defn_t * ifd, execfn * exec) |
394 |
{ |
{ |
395 |
return execute("ip tunnel del %iface%", ifd, exec); |
return execute("ip tunnel del %iface%", ifd, exec); |
396 |
} |
} |
412 |
#endif /* FEATURE_IFUPDOWN_IPV6 */ |
#endif /* FEATURE_IFUPDOWN_IPV6 */ |
413 |
|
|
414 |
#if ENABLE_FEATURE_IFUPDOWN_IPV4 |
#if ENABLE_FEATURE_IFUPDOWN_IPV4 |
415 |
static int loopback_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC loopback_up(struct interface_defn_t *ifd, execfn *exec) |
416 |
{ |
{ |
417 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
418 |
int result; |
int result; |
424 |
#endif |
#endif |
425 |
} |
} |
426 |
|
|
427 |
static int loopback_down(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC loopback_down(struct interface_defn_t *ifd, execfn *exec) |
428 |
{ |
{ |
429 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
430 |
int result; |
int result; |
436 |
#endif |
#endif |
437 |
} |
} |
438 |
|
|
439 |
static int static_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC static_up(struct interface_defn_t *ifd, execfn *exec) |
440 |
{ |
{ |
441 |
int result; |
int result; |
442 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
458 |
#endif |
#endif |
459 |
} |
} |
460 |
|
|
461 |
static int static_down(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC static_down(struct interface_defn_t *ifd, execfn *exec) |
462 |
{ |
{ |
463 |
int result; |
int result; |
464 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
475 |
} |
} |
476 |
|
|
477 |
#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP |
#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP |
478 |
struct dhcp_client_t |
struct dhcp_client_t { |
|
{ |
|
479 |
const char *name; |
const char *name; |
480 |
const char *startcmd; |
const char *startcmd; |
481 |
const char *stopcmd; |
const char *stopcmd; |
495 |
"pump -i %iface% -k", |
"pump -i %iface% -k", |
496 |
}, |
}, |
497 |
{ "udhcpc", |
{ "udhcpc", |
498 |
"udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]]" |
"udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]]" |
499 |
"[[ -s %script%]][[ %udhcpc_opts%]]", |
"[[ -s %script%]][[ %udhcpc_opts%]]", |
500 |
"kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", |
"kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", |
501 |
}, |
}, |
503 |
#endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */ |
#endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */ |
504 |
|
|
505 |
#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP |
#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP |
506 |
static int dhcp_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC dhcp_up(struct interface_defn_t *ifd, execfn *exec) |
507 |
{ |
{ |
508 |
unsigned i; |
unsigned i; |
509 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
522 |
bb_error_msg("no dhcp clients found"); |
bb_error_msg("no dhcp clients found"); |
523 |
return 0; |
return 0; |
524 |
} |
} |
525 |
#elif ENABLE_APP_UDHCPC |
#elif ENABLE_UDHCPC |
526 |
static int dhcp_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC dhcp_up(struct interface_defn_t *ifd, execfn *exec) |
527 |
{ |
{ |
528 |
#if ENABLE_FEATURE_IFUPDOWN_IP |
#if ENABLE_FEATURE_IFUPDOWN_IP |
529 |
/* ip doesn't up iface when it configures it (unlike ifconfig) */ |
/* ip doesn't up iface when it configures it (unlike ifconfig) */ |
534 |
if (!execute("ifconfig %iface%[[ hw %hwaddress%]] up", ifd, exec)) |
if (!execute("ifconfig %iface%[[ hw %hwaddress%]] up", ifd, exec)) |
535 |
return 0; |
return 0; |
536 |
#endif |
#endif |
537 |
return execute("udhcpc -R -n -p /var/run/udhcpc.%iface%.pid " |
return execute("udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid " |
538 |
"-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ %udhcpc_opts%]]", |
"-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ %udhcpc_opts%]]", |
539 |
ifd, exec); |
ifd, exec); |
540 |
} |
} |
541 |
#else |
#else |
542 |
static int dhcp_up(struct interface_defn_t *ifd UNUSED_PARAM, |
static int FAST_FUNC dhcp_up(struct interface_defn_t *ifd UNUSED_PARAM, |
543 |
execfn *exec UNUSED_PARAM) |
execfn *exec UNUSED_PARAM) |
544 |
{ |
{ |
545 |
return 0; /* no dhcp support */ |
return 0; /* no dhcp support */ |
547 |
#endif |
#endif |
548 |
|
|
549 |
#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP |
#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP |
550 |
static int dhcp_down(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC dhcp_down(struct interface_defn_t *ifd, execfn *exec) |
551 |
{ |
{ |
552 |
int result = 0; |
int result = 0; |
553 |
unsigned i; |
unsigned i; |
554 |
|
|
555 |
for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { |
for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { |
556 |
if (exists_execable(ext_dhcp_clients[i].name)) { |
if (exists_execable(ext_dhcp_clients[i].name)) { |
557 |
result += execute(ext_dhcp_clients[i].stopcmd, ifd, exec); |
result = execute(ext_dhcp_clients[i].stopcmd, ifd, exec); |
558 |
if (result) |
if (result) |
559 |
break; |
break; |
560 |
} |
} |
569 |
result += static_down(ifd, exec); |
result += static_down(ifd, exec); |
570 |
return ((result == 3) ? 3 : 0); |
return ((result == 3) ? 3 : 0); |
571 |
} |
} |
572 |
#elif ENABLE_APP_UDHCPC |
#elif ENABLE_UDHCPC |
573 |
static int dhcp_down(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC dhcp_down(struct interface_defn_t *ifd, execfn *exec) |
574 |
{ |
{ |
575 |
int result; |
int result; |
576 |
result = execute("kill " |
result = execute("kill " |
585 |
return ((result == 3) ? 3 : 0); |
return ((result == 3) ? 3 : 0); |
586 |
} |
} |
587 |
#else |
#else |
588 |
static int dhcp_down(struct interface_defn_t *ifd UNUSED_PARAM, |
static int FAST_FUNC dhcp_down(struct interface_defn_t *ifd UNUSED_PARAM, |
589 |
execfn *exec UNUSED_PARAM) |
execfn *exec UNUSED_PARAM) |
590 |
{ |
{ |
591 |
return 0; /* no dhcp support */ |
return 0; /* no dhcp support */ |
592 |
} |
} |
593 |
#endif |
#endif |
594 |
|
|
595 |
static int manual_up_down(struct interface_defn_t *ifd UNUSED_PARAM, execfn *exec UNUSED_PARAM) |
static int FAST_FUNC manual_up_down(struct interface_defn_t *ifd UNUSED_PARAM, execfn *exec UNUSED_PARAM) |
596 |
{ |
{ |
597 |
return 1; |
return 1; |
598 |
} |
} |
599 |
|
|
600 |
static int bootp_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC bootp_up(struct interface_defn_t *ifd, execfn *exec) |
601 |
{ |
{ |
602 |
return execute("bootpc[[ --bootfile %bootfile%]] --dev %iface%" |
return execute("bootpc[[ --bootfile %bootfile%]] --dev %iface%" |
603 |
"[[ --server %server%]][[ --hwaddr %hwaddr%]]" |
"[[ --server %server%]][[ --hwaddr %hwaddr%]]" |
604 |
" --returniffail --serverbcast", ifd, exec); |
" --returniffail --serverbcast", ifd, exec); |
605 |
} |
} |
606 |
|
|
607 |
static int ppp_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC ppp_up(struct interface_defn_t *ifd, execfn *exec) |
608 |
{ |
{ |
609 |
return execute("pon[[ %provider%]]", ifd, exec); |
return execute("pon[[ %provider%]]", ifd, exec); |
610 |
} |
} |
611 |
|
|
612 |
static int ppp_down(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC ppp_down(struct interface_defn_t *ifd, execfn *exec) |
613 |
{ |
{ |
614 |
return execute("poff[[ %provider%]]", ifd, exec); |
return execute("poff[[ %provider%]]", ifd, exec); |
615 |
} |
} |
616 |
|
|
617 |
static int wvdial_up(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC wvdial_up(struct interface_defn_t *ifd, execfn *exec) |
618 |
{ |
{ |
619 |
return execute("start-stop-daemon --start -x wvdial " |
return execute("start-stop-daemon --start -x wvdial " |
620 |
"-p /var/run/wvdial.%iface% -b -m --[[ %provider%]]", ifd, exec); |
"-p /var/run/wvdial.%iface% -b -m --[[ %provider%]]", ifd, exec); |
621 |
} |
} |
622 |
|
|
623 |
static int wvdial_down(struct interface_defn_t *ifd, execfn *exec) |
static int FAST_FUNC wvdial_down(struct interface_defn_t *ifd, execfn *exec) |
624 |
{ |
{ |
625 |
return execute("start-stop-daemon --stop -x wvdial " |
return execute("start-stop-daemon --stop -x wvdial " |
626 |
"-p /var/run/wvdial.%iface% -s 2", ifd, exec); |
"-p /var/run/wvdial.%iface% -s 2", ifd, exec); |
627 |
} |
} |
628 |
|
|
629 |
static const struct method_t methods[] = { |
static const struct method_t methods[] = { |
630 |
{ "manual", manual_up_down, manual_up_down, }, |
{ "manual" , manual_up_down, manual_up_down, }, |
631 |
{ "wvdial", wvdial_up, wvdial_down, }, |
{ "wvdial" , wvdial_up , wvdial_down , }, |
632 |
{ "ppp", ppp_up, ppp_down, }, |
{ "ppp" , ppp_up , ppp_down , }, |
633 |
{ "static", static_up, static_down, }, |
{ "static" , static_up , static_down , }, |
634 |
{ "bootp", bootp_up, static_down, }, |
{ "bootp" , bootp_up , static_down , }, |
635 |
{ "dhcp", dhcp_up, dhcp_down, }, |
{ "dhcp" , dhcp_up , dhcp_down , }, |
636 |
{ "loopback", loopback_up, loopback_down, }, |
{ "loopback", loopback_up , loopback_down , }, |
637 |
}; |
}; |
638 |
|
|
639 |
static const struct address_family_t addr_inet = { |
static const struct address_family_t addr_inet = { |
644 |
|
|
645 |
#endif /* if ENABLE_FEATURE_IFUPDOWN_IPV4 */ |
#endif /* if ENABLE_FEATURE_IFUPDOWN_IPV4 */ |
646 |
|
|
647 |
|
/* Returns pointer to the next word, or NULL. |
648 |
|
* In 1st case, advances *buf to the word after this one. |
649 |
|
*/ |
650 |
static char *next_word(char **buf) |
static char *next_word(char **buf) |
651 |
{ |
{ |
652 |
unsigned length; |
unsigned length; |
666 |
if (word[length] != '\0') |
if (word[length] != '\0') |
667 |
word[length++] = '\0'; |
word[length++] = '\0'; |
668 |
|
|
669 |
*buf = word + length; |
*buf = skip_whitespace(word + length); |
670 |
|
|
671 |
return word; |
return word; |
672 |
} |
} |
701 |
return NULL; |
return NULL; |
702 |
} |
} |
703 |
|
|
|
static const llist_t *find_list_string(const llist_t *list, const char *string) |
|
|
{ |
|
|
if (string == NULL) |
|
|
return NULL; |
|
|
|
|
|
while (list) { |
|
|
if (strcmp(list->data, string) == 0) { |
|
|
return list; |
|
|
} |
|
|
list = list->link; |
|
|
} |
|
|
return NULL; |
|
|
} |
|
|
|
|
704 |
static struct interfaces_file_t *read_interfaces(const char *filename) |
static struct interfaces_file_t *read_interfaces(const char *filename) |
705 |
{ |
{ |
706 |
/* Let's try to be compatible. |
/* Let's try to be compatible. |
831 |
while ((first_word = next_word(&rest_of_line)) != NULL) { |
while ((first_word = next_word(&rest_of_line)) != NULL) { |
832 |
|
|
833 |
/* Check the interface isnt already listed */ |
/* Check the interface isnt already listed */ |
834 |
if (find_list_string(defn->autointerfaces, first_word)) { |
if (llist_find_str(defn->autointerfaces, first_word)) { |
835 |
bb_perror_msg_and_die("interface declared auto twice \"%s\"", buf); |
bb_perror_msg_and_die("interface declared auto twice \"%s\"", buf); |
836 |
} |
} |
837 |
|
|
906 |
static char *setlocalenv(const char *format, const char *name, const char *value) |
static char *setlocalenv(const char *format, const char *name, const char *value) |
907 |
{ |
{ |
908 |
char *result; |
char *result; |
909 |
char *here; |
char *dst; |
910 |
char *there; |
char *src; |
911 |
|
char c; |
912 |
|
|
913 |
result = xasprintf(format, name, value); |
result = xasprintf(format, name, value); |
914 |
|
|
915 |
for (here = there = result; *there != '=' && *there; there++) { |
for (dst = src = result; (c = *src) != '=' && c; src++) { |
916 |
if (*there == '-') |
if (c == '-') |
917 |
*there = '_'; |
c = '_'; |
918 |
if (isalpha(*there)) |
if (c >= 'a' && c <= 'z') |
919 |
*there = toupper(*there); |
c -= ('a' - 'A'); |
920 |
|
if (isalnum(c) || c == '_') |
921 |
if (isalnum(*there) || *there == '_') { |
*dst++ = c; |
|
*here = *there; |
|
|
here++; |
|
|
} |
|
922 |
} |
} |
923 |
memmove(here, there, strlen(there) + 1); |
overlapping_strcpy(dst, src); |
924 |
|
|
925 |
return result; |
return result; |
926 |
} |
} |
927 |
|
|
928 |
static void set_environ(struct interface_defn_t *iface, const char *mode) |
static void set_environ(struct interface_defn_t *iface, const char *mode) |
929 |
{ |
{ |
|
char **environend; |
|
930 |
int i; |
int i; |
931 |
const int n_env_entries = iface->n_options + 5; |
char **pp; |
|
char **ppch; |
|
932 |
|
|
933 |
if (my_environ != NULL) { |
if (G.my_environ != NULL) { |
934 |
for (ppch = my_environ; *ppch; ppch++) { |
for (pp = G.my_environ; *pp; pp++) { |
935 |
free(*ppch); |
free(*pp); |
|
*ppch = NULL; |
|
936 |
} |
} |
937 |
free(my_environ); |
free(G.my_environ); |
938 |
} |
} |
939 |
my_environ = xzalloc(sizeof(char *) * (n_env_entries + 1 /* for final NULL */ )); |
|
940 |
environend = my_environ; |
/* note: last element will stay NULL: */ |
941 |
|
G.my_environ = xzalloc(sizeof(char *) * (iface->n_options + 6)); |
942 |
|
pp = G.my_environ; |
943 |
|
|
944 |
for (i = 0; i < iface->n_options; i++) { |
for (i = 0; i < iface->n_options; i++) { |
945 |
if (strcmp(iface->option[i].name, "up") == 0 |
if (strcmp(iface->option[i].name, "up") == 0 |
949 |
) { |
) { |
950 |
continue; |
continue; |
951 |
} |
} |
952 |
*(environend++) = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); |
*pp++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); |
953 |
} |
} |
954 |
|
|
955 |
*(environend++) = setlocalenv("%s=%s", "IFACE", iface->iface); |
*pp++ = setlocalenv("%s=%s", "IFACE", iface->iface); |
956 |
*(environend++) = setlocalenv("%s=%s", "ADDRFAM", iface->address_family->name); |
*pp++ = setlocalenv("%s=%s", "ADDRFAM", iface->address_family->name); |
957 |
*(environend++) = setlocalenv("%s=%s", "METHOD", iface->method->name); |
*pp++ = setlocalenv("%s=%s", "METHOD", iface->method->name); |
958 |
*(environend++) = setlocalenv("%s=%s", "MODE", mode); |
*pp++ = setlocalenv("%s=%s", "MODE", mode); |
959 |
*(environend++) = setlocalenv("%s=%s", "PATH", startup_PATH); |
if (G.startup_PATH) |
960 |
|
*pp++ = setlocalenv("%s=%s", "PATH", G.startup_PATH); |
961 |
} |
} |
962 |
|
|
963 |
static int doit(char *str) |
static int doit(char *str) |
969 |
pid_t child; |
pid_t child; |
970 |
int status; |
int status; |
971 |
|
|
972 |
fflush(NULL); |
fflush_all(); |
973 |
child = vfork(); |
child = vfork(); |
974 |
switch (child) { |
switch (child) { |
975 |
case -1: /* failure */ |
case -1: /* failure */ |
976 |
return 0; |
return 0; |
977 |
case 0: /* child */ |
case 0: /* child */ |
978 |
execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, my_environ); |
execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, (char *) NULL, G.my_environ); |
979 |
_exit(127); |
_exit(127); |
980 |
} |
} |
981 |
safe_waitpid(child, &status, 0); |
safe_waitpid(child, &status, 0); |
1038 |
xpiped_pair(infd); |
xpiped_pair(infd); |
1039 |
xpiped_pair(outfd); |
xpiped_pair(outfd); |
1040 |
|
|
1041 |
fflush(NULL); |
fflush_all(); |
1042 |
pid = vfork(); |
pid = vfork(); |
1043 |
|
|
1044 |
switch (pid) { |
switch (pid) { |
1056 |
/* parent */ |
/* parent */ |
1057 |
close(infd.rd); |
close(infd.rd); |
1058 |
close(outfd.wr); |
close(outfd.wr); |
1059 |
*in = fdopen(infd.wr, "w"); |
*in = xfdopen_for_write(infd.wr); |
1060 |
*out = fdopen(outfd.rd, "r"); |
*out = xfdopen_for_read(outfd.rd); |
1061 |
return pid; |
return pid; |
1062 |
} |
} |
1063 |
|
|
1142 |
|
|
1143 |
|
|
1144 |
int ifupdown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
int ifupdown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1145 |
int ifupdown_main(int argc, char **argv) |
int ifupdown_main(int argc UNUSED_PARAM, char **argv) |
1146 |
{ |
{ |
1147 |
int (*cmds)(struct interface_defn_t *); |
int (*cmds)(struct interface_defn_t *); |
1148 |
struct interfaces_file_t *defn; |
struct interfaces_file_t *defn; |
1150 |
const char *interfaces = "/etc/network/interfaces"; |
const char *interfaces = "/etc/network/interfaces"; |
1151 |
bool any_failures = 0; |
bool any_failures = 0; |
1152 |
|
|
1153 |
|
INIT_G(); |
1154 |
|
|
1155 |
|
G.startup_PATH = getenv("PATH"); |
1156 |
|
|
1157 |
cmds = iface_down; |
cmds = iface_down; |
1158 |
if (applet_name[2] == 'u') { |
if (applet_name[2] == 'u') { |
1159 |
/* ifup command */ |
/* ifup command */ |
1161 |
} |
} |
1162 |
|
|
1163 |
getopt32(argv, OPTION_STR, &interfaces); |
getopt32(argv, OPTION_STR, &interfaces); |
1164 |
if (argc - optind > 0) { |
argv += optind; |
1165 |
|
if (argv[0]) { |
1166 |
if (DO_ALL) bb_show_usage(); |
if (DO_ALL) bb_show_usage(); |
1167 |
} else { |
} else { |
1168 |
if (!DO_ALL) bb_show_usage(); |
if (!DO_ALL) bb_show_usage(); |
1172 |
defn = read_interfaces(interfaces); |
defn = read_interfaces(interfaces); |
1173 |
debug_noise("\ndone reading %s\n\n", interfaces); |
debug_noise("\ndone reading %s\n\n", interfaces); |
1174 |
|
|
|
startup_PATH = getenv("PATH"); |
|
|
if (!startup_PATH) startup_PATH = ""; |
|
|
|
|
1175 |
/* Create a list of interfaces to work on */ |
/* Create a list of interfaces to work on */ |
1176 |
if (DO_ALL) { |
if (DO_ALL) { |
1177 |
target_list = defn->autointerfaces; |
target_list = defn->autointerfaces; |
1178 |
} else { |
} else { |
1179 |
llist_add_to_end(&target_list, argv[optind]); |
llist_add_to_end(&target_list, argv[0]); |
1180 |
} |
} |
1181 |
|
|
1182 |
/* Update the interfaces */ |
/* Update the interfaces */ |