+--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.
# 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
#ifdef __linux__
# include <netinet/ether.h>
#endif
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
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 ()) {
* 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
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
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifdef __linux__
+# define _GNU_SOURCE /* for asprinf */
+#endif
+
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
}
#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 */
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)
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)
{"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}
};
options.daemonised = true;
close_fds ();
break;
+ case 'g':
+ dhcpcd_skiproutes = xstrdup (optarg);
+ break;
#endif
case 'h':
if (! optarg)
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)
#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 {