From: Roy Marples Date: Thu, 4 Oct 2007 09:57:50 +0000 (+0000) Subject: --skiproutes has been added for no fork users so that we know if we can delete the... X-Git-Tag: v3.2.3~200 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1f501245e403507e249701ac5d1ed6899051ab8;p=thirdparty%2Fdhcpcd.git --skiproutes has been added for no fork users so that we know if we can delete the route at a later date. --- diff --git a/ChangeLog b/ChangeLog index ef958b2b..a43316ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +--skiproutes has been added for no fork users so that we know if we +can delete the route at a later date. Many thanks to Michael Durrant for testing the below changes. Compile and work on OSX/Darwin. If we have no fork then we re-exec ourselves with --daemonised. diff --git a/Makefile b/Makefile index 56ede2b5..ab39b17e 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # such as the need to link to libresolv and/or librt so please forgive the # embedded code :) -VERSION = 3.1.6_pre6 +VERSION = 3.1.6_pre8 CFLAGS += -O2 -pipe INSTALL ?= install diff --git a/client.c b/client.c index 0c17d838..8572a48b 100644 --- a/client.c +++ b/client.c @@ -32,6 +32,7 @@ #ifdef __linux__ # include #endif +#include #include #include #include @@ -139,10 +140,14 @@ static pid_t daemonise (int *pidfd) logger (LOG_INFO, "forking to background"); /* We need to add --daemonise to our options */ - argv = xmalloc (sizeof (char *) * (dhcpcd_argc + 2)); + argv = xmalloc (sizeof (char *) * (dhcpcd_argc + 4)); for (i = 0; i < dhcpcd_argc; i++) argv[i] = dhcpcd_argv[i]; argv[i] = (char *) "--daemonised"; + if (dhcpcd_skiproutes) { + argv[++i] = (char *) "--skiproutes"; + argv[++i] = dhcpcd_skiproutes; + } argv[i + 1] = NULL; switch (pid = vfork ()) { @@ -292,19 +297,45 @@ int dhcp_run (const options_t *options, int *pidfd) * This is especially true on BSD platforms where we can only * have one default route. */ if (dhcp->routes) { + int i = -1; route_t *droute; - route_t *iroute; + route_t *iroute = NULL; free_route (iface->previous_routes); - iroute = iface->previous_routes = xmalloc (sizeof (route_t)); for (droute = dhcp->routes; droute; droute = droute->next) { + i++; + + /* Check that we did add this route or not */ + if (dhcpcd_skiproutes) { + char *sk = xstrdup (dhcpcd_skiproutes); + char *skp = sk; + char *token; + bool found = false; + + while ((token = strsep (&skp, ","))) { + if (isdigit (*token) && atoi (token) == i) { + found = true; + break; + } + } + free (sk); + if (found) + continue; + } + + if (! iroute) + iroute = iface->previous_routes = xmalloc (sizeof (route_t)); memcpy (iroute, droute, sizeof (route_t)); if (droute->next) { iroute->next = xmalloc (sizeof (route_t)); iroute = iroute->next; } } + + /* We no longer need this argument */ + free (dhcpcd_skiproutes); + dhcpcd_skiproutes = NULL; } } #endif @@ -478,16 +509,18 @@ int dhcp_run (const options_t *options, int *pidfd) free_dhcp (dhcp); memset (dhcp, 0, sizeof (dhcp_t)); #ifdef ENABLE_INFO - if (! options->test && - ! get_old_lease (options, iface, dhcp, &timeout)) + if (! options->test && + (options->doipv4ll || options->dolastlease)) { - if (options->dolastlease) { - retval = EXIT_FAILURE; - goto eexit; + if (! get_old_lease (options, iface, dhcp, &timeout)) + { + if (options->dolastlease) { + retval = EXIT_FAILURE; + goto eexit; + } + free_dhcp (dhcp); + memset (dhcp, 0, sizeof (dhcp_t)); } - - free_dhcp (dhcp); - memset (dhcp, 0, sizeof (dhcp_t)); } #endif diff --git a/configure.c b/configure.c index eb751bc0..7ecf6fc8 100644 --- a/configure.c +++ b/configure.c @@ -19,6 +19,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifdef __linux__ +# define _GNU_SOURCE /* for asprinf */ +#endif + #include #include #include @@ -433,10 +437,18 @@ int configure (const options_t *options, interface_t *iface, } #endif +#ifdef THERE_IS_NO_FORK + free (dhcpcd_skiproutes); + dhcpcd_skiproutes = NULL; +#endif + /* Remember added routes */ if (dhcp->routes) { route_t *new_routes = NULL; int remember; +#ifdef THERE_IS_NO_FORK + int skip = 0; +#endif for (route = dhcp->routes; route; route = route->next) { /* Don't set default routes if not asked to */ @@ -472,6 +484,21 @@ int configure (const options_t *options, interface_t *iface, memcpy (new_route, route, sizeof (route_t)); new_route -> next = NULL; } +#ifdef THERE_IS_NO_FORK + /* If we have daemonised yet we need to record which routes + * we failed to add so we can skip them */ + else if (! options->daemonised) { + if (dhcpcd_skiproutes) { + char *p = NULL; + asprintf (&p, "%s,%d", dhcpcd_skiproutes, skip); + free (dhcpcd_skiproutes); + dhcpcd_skiproutes = p; + } else { + asprintf (&dhcpcd_skiproutes, "%d", skip); + } + } + skip++; +#endif } if (iface->previous_routes) diff --git a/dhcpcd.c b/dhcpcd.c index b54cbd2f..f9870520 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -66,6 +66,7 @@ char dhcpcd[PATH_MAX]; char **dhcpcd_argv = NULL; int dhcpcd_argc = 0; +char *dhcpcd_skiproutes = NULL; #endif static pid_t read_pid (const char *pidfile) @@ -137,6 +138,7 @@ int main(int argc, char **argv) {"version", no_argument, &doversion, 1}, #ifdef THERE_IS_NO_FORK {"daemonised", no_argument, NULL, 'f'}, + {"skiproutes", required_argument, NULL, 'g'}, #endif {NULL, 0, NULL, 0} }; @@ -200,6 +202,9 @@ int main(int argc, char **argv) options.daemonised = true; close_fds (); break; + case 'g': + dhcpcd_skiproutes = xstrdup (optarg); + break; #endif case 'h': if (! optarg) @@ -528,6 +533,12 @@ int main(int argc, char **argv) if (dhcp_run (&options, &pidfd) == 0) i = EXIT_SUCCESS; +#ifdef THERE_IS_NO_FORK + /* There may have been an error before the dhcp_run function + * clears this, so just do it here to be safe */ + free (dhcpcd_skiproutes); +#endif + logger (LOG_INFO, "exiting"); if (pidfd > -1) diff --git a/dhcpcd.h b/dhcpcd.h index fe0dbcdf..af8b4fb7 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -36,10 +36,11 @@ #define CLIENT_ID_MAX_LEN 48 #define USERCLASS_MAX_LEN 255 -#ifndef HAVE_FORK +#ifdef THERE_IS_NO_FORK extern char dhcpcd[PATH_MAX]; extern char **dhcpcd_argv; extern int dhcpcd_argc; +extern char *dhcpcd_skiproutes; #endif typedef struct options_t {