zcip: make it work on NOMMU (+ improve NOMMU support machinery)
fsck: fix bad English in a comment
This commit is contained in:
parent
4e1361a481
commit
afa7023b46
@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Automatically generated make config: don't edit
|
# Automatically generated make config: don't edit
|
||||||
# Busybox version: 1.6.0.svn
|
# Busybox version: 1.6.0.svn
|
||||||
# Mon Mar 26 15:00:56 2007
|
# Mon Mar 26 18:36:12 2007
|
||||||
#
|
#
|
||||||
CONFIG_HAVE_DOT_CONFIG=y
|
CONFIG_HAVE_DOT_CONFIG=y
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ CONFIG_RESET=y
|
|||||||
CONFIG_RESIZE=y
|
CONFIG_RESIZE=y
|
||||||
CONFIG_FEATURE_RESIZE_PRINT=y
|
CONFIG_FEATURE_RESIZE_PRINT=y
|
||||||
CONFIG_SETCONSOLE=y
|
CONFIG_SETCONSOLE=y
|
||||||
# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
|
CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y
|
||||||
CONFIG_SETKEYCODES=y
|
CONFIG_SETKEYCODES=y
|
||||||
CONFIG_SETLOGCONS=y
|
CONFIG_SETLOGCONS=y
|
||||||
|
|
||||||
@ -605,7 +605,7 @@ CONFIG_WGET=y
|
|||||||
CONFIG_FEATURE_WGET_STATUSBAR=y
|
CONFIG_FEATURE_WGET_STATUSBAR=y
|
||||||
CONFIG_FEATURE_WGET_AUTHENTICATION=y
|
CONFIG_FEATURE_WGET_AUTHENTICATION=y
|
||||||
CONFIG_FEATURE_WGET_LONG_OPTIONS=y
|
CONFIG_FEATURE_WGET_LONG_OPTIONS=y
|
||||||
# CONFIG_ZCIP is not set
|
CONFIG_ZCIP=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# Process Utilities
|
# Process Utilities
|
||||||
|
@ -509,12 +509,7 @@ static struct fsck_instance *wait_one(int flags)
|
|||||||
goto ret_inst;
|
goto ret_inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
inst = prev = NULL; /* for gcc */
|
||||||
* gcc -Wall fails saving throw against stupidity
|
|
||||||
* (inst and prev are thought to be uninitialized variables)
|
|
||||||
*/
|
|
||||||
inst = prev = NULL;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
pid = waitpid(-1, &status, flags);
|
pid = waitpid(-1, &status, flags);
|
||||||
kill_all_if_cancel_requested();
|
kill_all_if_cancel_requested();
|
||||||
|
@ -263,6 +263,13 @@ char *xrealloc_getcwd_or_warn(char *cwd);
|
|||||||
char *xmalloc_readlink_or_warn(const char *path);
|
char *xmalloc_readlink_or_warn(const char *path);
|
||||||
char *xmalloc_realpath(const char *path);
|
char *xmalloc_realpath(const char *path);
|
||||||
extern void xstat(const char *filename, struct stat *buf);
|
extern void xstat(const char *filename, struct stat *buf);
|
||||||
|
/* Unlike waitpid, waits ONLY for one process,
|
||||||
|
* It's safe to pass negative 'pids' from failed [v]fork -
|
||||||
|
* wait4pid will return -1 and ECHILD in errno.
|
||||||
|
* IOW: rc = wait4pid(spawn(argv));
|
||||||
|
* if (rc < 0) bb_perror_msg("%s", argv[0]);
|
||||||
|
* if (rc > 0) bb_error_msg("exit code: %d", rc);
|
||||||
|
*/
|
||||||
extern int wait4pid(int pid);
|
extern int wait4pid(int pid);
|
||||||
extern void xsetgid(gid_t gid);
|
extern void xsetgid(gid_t gid);
|
||||||
extern void xsetuid(uid_t uid);
|
extern void xsetuid(uid_t uid);
|
||||||
|
@ -40,11 +40,14 @@ pid_t spawn(char **argv)
|
|||||||
* (but don't run atexit() stuff, which would screw up parent.)
|
* (but don't run atexit() stuff, which would screw up parent.)
|
||||||
*/
|
*/
|
||||||
failed = errno;
|
failed = errno;
|
||||||
_exit(0);
|
_exit(111);
|
||||||
}
|
}
|
||||||
/* parent */
|
/* parent */
|
||||||
/* Unfortunately, this is not reliable: vfork()
|
/* Unfortunately, this is not reliable: according to standards
|
||||||
* can be equivalent to fork() according to standards */
|
* vfork() can be equivalent to fork() and we won't see value
|
||||||
|
* of 'failed'.
|
||||||
|
* Interested party can wait on pid and learn exit code.
|
||||||
|
* If 111 - then it (most probably) failed to exec */
|
||||||
if (failed) {
|
if (failed) {
|
||||||
errno = failed;
|
errno = failed;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -192,9 +192,16 @@ int wait4pid(int pid)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (pid == -1 || waitpid(pid, &status, 0) == -1) return -1;
|
if (pid <= 0) {
|
||||||
if (WIFEXITED(status)) return WEXITSTATUS(status);
|
errno = ECHILD;
|
||||||
if (WIFSIGNALED(status)) return WTERMSIG(status);
|
return -1;
|
||||||
|
}
|
||||||
|
if (waitpid(pid, &status, 0) == -1)
|
||||||
|
return -1;
|
||||||
|
if (WIFEXITED(status))
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
if (WIFSIGNALED(status))
|
||||||
|
return WTERMSIG(status) + 10000;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,10 +70,6 @@ enum {
|
|||||||
#define VDBG(fmt,args...) \
|
#define VDBG(fmt,args...) \
|
||||||
do { } while (0)
|
do { } while (0)
|
||||||
|
|
||||||
static unsigned opts;
|
|
||||||
#define FOREGROUND (opts & 1)
|
|
||||||
#define QUIT (opts & 2)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick a random link local IP address on 169.254/16, except that
|
* Pick a random link local IP address on 169.254/16, except that
|
||||||
* the first and last 256 addresses are reserved.
|
* the first and last 256 addresses are reserved.
|
||||||
@ -128,49 +124,30 @@ static void arp(int fd, struct sockaddr *saddr, int op,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a script.
|
* Run a script. argv[2] is already NULL.
|
||||||
*/
|
*/
|
||||||
static int run(const char *script, const char *arg, const char *intf, struct in_addr *ip)
|
static int run(char *argv[3], const char *intf, struct in_addr *ip)
|
||||||
{
|
{
|
||||||
int pid, status;
|
int status;
|
||||||
const char *why;
|
|
||||||
|
|
||||||
if(1) { //always true: if (script != NULL)
|
VDBG("%s run %s %s\n", intf, argv[0], argv[1]);
|
||||||
VDBG("%s run %s %s\n", intf, script, arg);
|
|
||||||
if (ip != NULL) {
|
|
||||||
char *addr = inet_ntoa(*ip);
|
|
||||||
setenv("ip", addr, 1);
|
|
||||||
bb_info_msg("%s %s %s", arg, intf, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
pid = vfork();
|
if (ip) {
|
||||||
if (pid < 0) { // error
|
char *addr = inet_ntoa(*ip);
|
||||||
why = "vfork";
|
setenv("ip", addr, 1);
|
||||||
goto bad;
|
bb_info_msg("%s %s %s", argv[1], intf, addr);
|
||||||
} else if (pid == 0) { // child
|
|
||||||
execl(script, script, arg, NULL);
|
|
||||||
bb_perror_msg("execl");
|
|
||||||
_exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waitpid(pid, &status, 0) <= 0) {
|
|
||||||
why = "waitpid";
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
if (WEXITSTATUS(status) != 0) {
|
|
||||||
bb_error_msg("script %s failed, exit=%d",
|
|
||||||
script, WEXITSTATUS(status));
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
bad:
|
status = wait4pid(spawn(argv));
|
||||||
status = -errno;
|
if (status < 0) {
|
||||||
bb_perror_msg("%s %s, %s", arg, intf, why);
|
bb_perror_msg("%s %s", argv[1], intf);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
if (status != 0)
|
||||||
|
bb_error_msg("script %s %s failed, exitcode=%d", argv[0], argv[1], status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return milliseconds of random delay, up to "secs" seconds.
|
* Return milliseconds of random delay, up to "secs" seconds.
|
||||||
*/
|
*/
|
||||||
@ -182,43 +159,58 @@ static unsigned ATTRIBUTE_ALWAYS_INLINE ms_rdelay(unsigned secs)
|
|||||||
/**
|
/**
|
||||||
* main program
|
* main program
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Used to be auto variables on main() stack, but
|
|
||||||
* most of them were zero-inited. Moving them to bss
|
|
||||||
* is more space-efficient.
|
|
||||||
*/
|
|
||||||
static const struct in_addr null_ip; // = { 0 };
|
|
||||||
static const struct ether_addr null_addr; // = { {0, 0, 0, 0, 0, 0} };
|
|
||||||
|
|
||||||
static struct sockaddr saddr; // memset(0);
|
|
||||||
static struct in_addr ip; // = { 0 };
|
|
||||||
static struct ifreq ifr; //memset(0);
|
|
||||||
|
|
||||||
static char *intf; // = NULL;
|
|
||||||
static char *script; // = NULL;
|
|
||||||
static suseconds_t timeout; // = 0; // milliseconds
|
|
||||||
static unsigned conflicts; // = 0;
|
|
||||||
static unsigned nprobes; // = 0;
|
|
||||||
static unsigned nclaims; // = 0;
|
|
||||||
static int ready; // = 0;
|
|
||||||
static int verbose; // = 0;
|
|
||||||
static int state = PROBE;
|
|
||||||
|
|
||||||
int zcip_main(int argc, char *argv[]);
|
int zcip_main(int argc, char *argv[]);
|
||||||
int zcip_main(int argc, char *argv[])
|
int zcip_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
int state = PROBE;
|
||||||
struct ether_addr eth_addr;
|
struct ether_addr eth_addr;
|
||||||
const char *why;
|
const char *why;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
// parse commandline: prog [options] ifname script
|
|
||||||
char *r_opt;
|
char *r_opt;
|
||||||
opt_complementary = "vv:vf"; // -v accumulates and implies -f
|
unsigned opts;
|
||||||
|
|
||||||
|
/* Ugly trick, but I want these zeroed in one go */
|
||||||
|
struct {
|
||||||
|
const struct in_addr null_ip;
|
||||||
|
const struct ether_addr null_addr;
|
||||||
|
struct sockaddr saddr;
|
||||||
|
struct in_addr ip;
|
||||||
|
struct ifreq ifr;
|
||||||
|
char *intf;
|
||||||
|
char *script_av[3];
|
||||||
|
suseconds_t timeout; // milliseconds
|
||||||
|
unsigned conflicts;
|
||||||
|
unsigned nprobes;
|
||||||
|
unsigned nclaims;
|
||||||
|
int ready;
|
||||||
|
int verbose;
|
||||||
|
} L;
|
||||||
|
#define null_ip (L.null_ip )
|
||||||
|
#define null_addr (L.null_addr)
|
||||||
|
#define saddr (L.saddr )
|
||||||
|
#define ip (L.ip )
|
||||||
|
#define ifr (L.ifr )
|
||||||
|
#define intf (L.intf )
|
||||||
|
#define script_av (L.script_av)
|
||||||
|
#define timeout (L.timeout )
|
||||||
|
#define conflicts (L.conflicts)
|
||||||
|
#define nprobes (L.nprobes )
|
||||||
|
#define nclaims (L.nclaims )
|
||||||
|
#define ready (L.ready )
|
||||||
|
#define verbose (L.verbose )
|
||||||
|
|
||||||
|
memset(&L, 0, sizeof(L));
|
||||||
|
|
||||||
|
#define FOREGROUND (opts & 1)
|
||||||
|
#define QUIT (opts & 2)
|
||||||
|
// parse commandline: prog [options] ifname script
|
||||||
|
// exactly 2 args; -v accumulates and implies -f
|
||||||
|
opt_complementary = "=2:vv:vf";
|
||||||
opts = getopt32(argc, argv, "fqr:v", &r_opt, &verbose);
|
opts = getopt32(argc, argv, "fqr:v", &r_opt, &verbose);
|
||||||
if (!FOREGROUND) {
|
if (!FOREGROUND) {
|
||||||
/* Do it early, before all bb_xx_msg calls */
|
/* Do it early, before all bb_xx_msg calls */
|
||||||
logmode = LOGMODE_SYSLOG;
|
|
||||||
openlog(applet_name, 0, LOG_DAEMON);
|
openlog(applet_name, 0, LOG_DAEMON);
|
||||||
|
logmode |= LOGMODE_SYSLOG;
|
||||||
}
|
}
|
||||||
if (opts & 4) { // -r n.n.n.n
|
if (opts & 4) { // -r n.n.n.n
|
||||||
if (inet_aton(r_opt, &ip) == 0
|
if (inet_aton(r_opt, &ip) == 0
|
||||||
@ -227,16 +219,21 @@ int zcip_main(int argc, char *argv[])
|
|||||||
bb_error_msg_and_die("invalid link address");
|
bb_error_msg_and_die("invalid link address");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// On NOMMU reexec early (or else we will rerun things twice)
|
||||||
|
#ifdef BB_NOMMU
|
||||||
|
if (!FOREGROUND)
|
||||||
|
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
|
||||||
|
#endif
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
if (argc != 2)
|
|
||||||
bb_show_usage();
|
|
||||||
intf = argv[0];
|
intf = argv[0];
|
||||||
script = argv[1];
|
script_av[0] = argv[1];
|
||||||
setenv("interface", intf, 1);
|
setenv("interface", intf, 1);
|
||||||
|
|
||||||
// initialize the interface (modprobe, ifup, etc)
|
// initialize the interface (modprobe, ifup, etc)
|
||||||
if (run(script, "init", intf, NULL) < 0)
|
script_av[1] = (char*)"init";
|
||||||
|
if (run(script_av, intf, NULL))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
// initialize saddr
|
// initialize saddr
|
||||||
@ -271,8 +268,9 @@ int zcip_main(int argc, char *argv[])
|
|||||||
|
|
||||||
// daemonize now; don't delay system startup
|
// daemonize now; don't delay system startup
|
||||||
if (!FOREGROUND) {
|
if (!FOREGROUND) {
|
||||||
//NOMMU
|
#ifndef BB_NOMMU
|
||||||
bb_daemonize(DAEMON_CHDIR_ROOT);
|
bb_daemonize(DAEMON_CHDIR_ROOT);
|
||||||
|
#endif
|
||||||
bb_info_msg("start, interface %s", intf);
|
bb_info_msg("start, interface %s", intf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +373,8 @@ int zcip_main(int argc, char *argv[])
|
|||||||
state = MONITOR;
|
state = MONITOR;
|
||||||
// link is ok to use earlier
|
// link is ok to use earlier
|
||||||
// FIXME update filters
|
// FIXME update filters
|
||||||
run(script, "config", intf, &ip);
|
script_av[1] = (char*)"config";
|
||||||
|
run(script_av, intf, &ip);
|
||||||
ready = 1;
|
ready = 1;
|
||||||
conflicts = 0;
|
conflicts = 0;
|
||||||
timeout = -1; // Never timeout in the monitor state.
|
timeout = -1; // Never timeout in the monitor state.
|
||||||
@ -429,8 +428,8 @@ int zcip_main(int argc, char *argv[])
|
|||||||
// this shouldn't necessarily exit.
|
// this shouldn't necessarily exit.
|
||||||
bb_error_msg("%s: poll error", intf);
|
bb_error_msg("%s: poll error", intf);
|
||||||
if (ready) {
|
if (ready) {
|
||||||
run(script, "deconfig",
|
script_av[1] = (char*)"deconfig";
|
||||||
intf, &ip);
|
run(script_av, intf, &ip);
|
||||||
}
|
}
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -516,7 +515,8 @@ int zcip_main(int argc, char *argv[])
|
|||||||
state = PROBE;
|
state = PROBE;
|
||||||
VDBG("defend conflict -- starting over\n");
|
VDBG("defend conflict -- starting over\n");
|
||||||
ready = 0;
|
ready = 0;
|
||||||
run(script, "deconfig", intf, &ip);
|
script_av[1] = (char*)"deconfig";
|
||||||
|
run(script_av, intf, &ip);
|
||||||
|
|
||||||
// restart the whole protocol
|
// restart the whole protocol
|
||||||
pick(&ip);
|
pick(&ip);
|
||||||
@ -542,7 +542,7 @@ int zcip_main(int argc, char *argv[])
|
|||||||
goto bad;
|
goto bad;
|
||||||
} // switch poll
|
} // switch poll
|
||||||
}
|
}
|
||||||
bad:
|
bad:
|
||||||
bb_perror_msg("%s, %s", intf, why);
|
bb_perror_msg("%s, %s", intf, why);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user