Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/ifupdown.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 17  Line 17 
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
# Line 31  Line 31 
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 */
# Line 40  typedef int execfn(char *command); Line 42  typedef int execfn(char *command);
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 {
# Line 85  struct interfaces_file_t { Line 87  struct interfaces_file_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    
# Line 124  static int strncmpz(const char *l, const Line 132  static int strncmpz(const char *l, const
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    
# Line 133  static char *get_var(const char *id, siz Line 141  static char *get_var(const char *id, siz
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;
# Line 323  static int execute(const char *command, Line 332  static int execute(const char *command,
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;
# Line 335  static int loopback_up6(struct interface Line 344  static int loopback_up6(struct interface
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);
# Line 344  static int loopback_down6(struct interfa Line 353  static int loopback_down6(struct interfa
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
# Line 360  static int static_up6(struct interface_d Line 369  static int static_up6(struct interface_d
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);
# Line 370  static int static_down6(struct interface Line 379  static int static_down6(struct interface
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 "
# Line 381  static int v4tunnel_up(struct interface_ Line 390  static int v4tunnel_up(struct interface_
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  }  }
# Line 403  static const struct address_family_t add Line 412  static const struct address_family_t add
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;
# Line 415  static int loopback_up(struct interface_ Line 424  static int loopback_up(struct interface_
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;
# Line 427  static int loopback_down(struct interfac Line 436  static int loopback_down(struct interfac
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
# Line 449  static int static_up(struct interface_de Line 458  static int static_up(struct interface_de
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
# Line 466  static int static_down(struct interface_ Line 475  static int static_down(struct interface_
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;
# Line 487  static const struct dhcp_client_t ext_dh Line 495  static const struct dhcp_client_t ext_dh
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   },   },
# Line 495  static const struct dhcp_client_t ext_dh Line 503  static const struct dhcp_client_t ext_dh
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
# Line 514  static int dhcp_up(struct interface_defn Line 522  static int dhcp_up(struct interface_defn
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) */
# Line 526  static int dhcp_up(struct interface_defn Line 534  static int dhcp_up(struct interface_defn
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 */
# Line 539  static int dhcp_up(struct interface_defn Line 547  static int dhcp_up(struct interface_defn
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   }   }
# Line 561  static int dhcp_down(struct interface_de Line 569  static int dhcp_down(struct interface_de
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 "
# Line 577  static int dhcp_down(struct interface_de Line 585  static int dhcp_down(struct interface_de
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 = {
# Line 636  static const struct address_family_t add Line 644  static const struct address_family_t add
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;
# Line 655  static char *next_word(char **buf) Line 666  static char *next_word(char **buf)
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  }  }
# Line 690  static const struct method_t *get_method Line 701  static const struct method_t *get_method
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.
# Line 834  static struct interfaces_file_t *read_in Line 831  static struct interfaces_file_t *read_in
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    
# Line 909  static struct interfaces_file_t *read_in Line 906  static struct interfaces_file_t *read_in
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
# Line 955  static void set_environ(struct interface Line 949  static void set_environ(struct interface
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)
# Line 974  static int doit(char *str) Line 969  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);
# Line 1043  static int popen2(FILE **in, FILE **out, Line 1038  static int popen2(FILE **in, FILE **out,
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) {
# Line 1061  static int popen2(FILE **in, FILE **out, Line 1056  static int popen2(FILE **in, FILE **out,
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    
# Line 1147  static llist_t *read_iface_state(void) Line 1142  static llist_t *read_iface_state(void)
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;
# Line 1155  int ifupdown_main(int argc, char **argv) Line 1150  int ifupdown_main(int argc, char **argv)
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 */
# Line 1162  int ifupdown_main(int argc, char **argv) Line 1161  int ifupdown_main(int argc, char **argv)
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();
# Line 1172  int ifupdown_main(int argc, char **argv) Line 1172  int ifupdown_main(int argc, char **argv)
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 */

Legend:
Removed from v.983  
changed lines
  Added in v.984