]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Allow a config file to be specified on the command line.
authorRoy Marples <roy@marples.name>
Thu, 24 Apr 2008 13:18:59 +0000 (13:18 +0000)
committerRoy Marples <roy@marples.name>
Thu, 24 Apr 2008 13:18:59 +0000 (13:18 +0000)
config.h
dhcpcd.8.in
dhcpcd.c

index 87df1ea73bd98fee046300692bc18d5a0c11c404..9e36197971d2ff62d48a804001521b4352036bde 100644 (file)
--- a/config.h
+++ b/config.h
@@ -61,7 +61,7 @@
 
 #define RESOLVFILE             "/etc/resolv.conf"
 #define CONFIGFILE             SYSCONFDIR "/" PACKAGE ".conf"
-#define DEFAULTSCRIPT          SYSCONFDIR "/" PACKAGE ".sh"
+#define SCRIPT                 SYSCONFDIR "/" PACKAGE ".sh"
 #define DUIDFILE               SYSCONFDIR "/" PACKAGE ".duid"
 #define LEASEFILE              DBDIR "/" PACKAGE "-%s.lease"
 #define PIDFILE                        RUNDIR "/" PACKAGE "-%s.pid"
index fa4f00de767aa7a83c51b60dd00a6a803c9dc443..b03bf350debfd32a316ed254a8a7adca0fc440de 100644 (file)
@@ -31,6 +31,7 @@
 .Nm
 .Op Fl dknpAEGLSTV
 .Op Fl c , -script Ar script
+.Op Fl f , -config Ar file
 .Op Fl h , -hostname Ar hostname
 .Op Fl i , -classid Ar classid
 .Op Fl l , -leasetime Ar seconds
@@ -115,13 +116,17 @@ ignores the exist code of the script.
 .Ss Fine tuning
 You can fine tune the behaviour of
 .Nm
-with the following options :-
+with the following options:
 .Bl -tag -width indent
 .It Fl d , -debug
 Echo debug and informational messages to the console.
 Subsequent debug options stop
 .Nm
 from daemonising.
+.It Fl f , -config Ar file
+Specify a config to load instead of @SYSCONFDIR@/dhcpcd.conf.
+.Nm
+always processes the config file before any command line options.
 .It Fl h , -hostname Ar hostname
 By default,
 .Nm
index 9d6079306d9deec8ab5bbb2f458fe1aae093ed44..f6c7be0e48d907f1f8d04e4ee8d79f752accdd93 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -49,12 +49,17 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples";
 #include "net.h"
 #include "logger.h"
 
+/* Don't set any optional arguments here so we retain POSIX
+ * compatibility with getopt */
+#define OPTS "c:df:h:i:kl:m:no:pr:s:t:u:xAEF:GHI:LO:STV"
+
 static int doversion = 0;
 static int dohelp = 0;
 static const struct option longopts[] = {
        {"arp",         no_argument,        NULL, 'a'},
        {"script",      required_argument,  NULL, 'c'},
        {"debug",       no_argument,        NULL, 'd'},
+       {"config",      required_argument,  NULL, 'f'},
        {"hostname",    optional_argument,  NULL, 'h'},
        {"classid",     optional_argument,  NULL, 'i'},
        {"release",     no_argument,        NULL, 'k'},
@@ -79,8 +84,8 @@ static const struct option longopts[] = {
        {"help",        no_argument,        &dohelp, 1},
        {"version",     no_argument,        &doversion, 1},
 #ifdef THERE_IS_NO_FORK
-       {"daemonised",  no_argument,        NULL, 'f'},
-       {"skiproutes",  required_argument,  NULL, 'g'},
+       {"daemonised",  no_argument,        NULL, 'X'},
+       {"skiproutes",  required_argument,  NULL, 'Z'},
 #endif
 #ifdef CMDLINE_COMPAT
        {"nohostname",  no_argument,        NULL, 'H'},
@@ -97,7 +102,7 @@ char dhcpcd[PATH_MAX];
 char **dhcpcd_argv = NULL;
 int dhcpcd_argc = 0;
 char *dhcpcd_skiproutes = NULL;
-#define EXTRA_OPTS "fg:"
+#define EXTRA_OPTS "XZ:"
 #elif CMDLINE_COMAPT
 # define EXTRA_OPTS "NRSY"
 #endif
@@ -144,7 +149,7 @@ read_pid(const char *pidfile)
 static void
 usage(void)
 {
-       printf("usage: "PACKAGE" [-adknpEGHLOSTV] [-c script] [-h hostname] [-i classID]\n"
+       printf("usage: "PACKAGE" [-adknpEGHLOSTV] [-c script] [-f file ] [-h hostname] [-i classID]\n"
               "              [-l leasetime] [-m metric] [-o option] [-r ipaddress]\n"
               "              [-s ipaddress] [-t timeout] [-u userclass] [-F none | ptr | both]\n"
               "              [-I clientID] <interface>\n");
@@ -365,6 +370,7 @@ main(int argc, char **argv)
        char lt = '\\';
        size_t len = 0;
        FILE *f;
+       char *cf = NULL;
 
        /* Close any un-needed fd's */
        for (i = getdtablesize() - 1; i >= 3; --i)
@@ -372,8 +378,18 @@ main(int argc, char **argv)
 
        openlog(PACKAGE, LOG_PID, LOG_LOCAL0);
 
+#ifdef THERE_IS_NO_FORK
+       dhcpcd_argv = argv;
+       dhcpcd_argc = argc;
+       if (!realpath(argv[0], dhcpcd)) {
+               fprintf(stderr, "unable to resolve the path `%s': %s",
+                               argv[0], strerror(errno));
+               goto abort;
+       }
+#endif
+
        options = xzalloc(sizeof(*options));
-       options->script = (char *)DEFAULTSCRIPT;
+       options->script = (char *)SCRIPT;
        snprintf(options->classid, CLASS_ID_MAX_LEN, "%s %s",
                 PACKAGE, VERSION);
 
@@ -386,8 +402,68 @@ main(int argc, char **argv)
            strcmp(options->hostname, "localhost") == 0)
                *options->hostname = '\0';
 
+       while ((opt = getopt_long(argc, argv, OPTS EXTRA_OPTS,
+                                 longopts, &option_index)) != -1)
+       {
+               switch (opt) {
+               case 0:
+                       if (longopts[option_index].flag)
+                               break;
+                       logger(LOG_ERR, "option `%s' should set a flag",
+                              longopts[option_index].name);
+                       goto abort;
+               case 'f':
+                       cf = optarg;
+                       break;
+               case '?':
+                       usage();
+                       goto abort;
+               }
+       }
+
+       if (doversion) {
+               printf(""PACKAGE" "VERSION"\n");
+               printf("Compile time options:"
+#ifdef ENABLE_ARP
+                       " ARP"
+#endif
+#ifdef ENABLE_DUID
+                       " DUID"
+#endif
+#ifdef ENABLE_IPV4LL
+                       " IPV4LL"
+#endif
+#ifdef THERE_IS_NO_FORK
+                       " THERE_IS_NO_FORK"
+#endif
+                       "\n");
+       }
+
+       if (dohelp)
+               usage();
+
+       if (optind < argc) {
+               if (strlen(argv[optind]) > IF_NAMESIZE) {
+                       logger(LOG_ERR,
+                              "`%s' too long for an interface name (max=%d)",
+                              argv[optind], IF_NAMESIZE);
+                       goto abort;
+               }
+               strlcpy(options->interface, argv[optind],
+                       sizeof(options->interface));
+       } else {
+               /* If only version was requested then exit now */
+               if (doversion || dohelp) {
+                       retval = 0;
+                       goto abort;
+               }
+
+               logger(LOG_ERR, "no interface specified");
+               goto abort;
+       }
+
        /* Parse our options file */
-       f = fopen(CONFIGFILE, "r");
+       f = fopen(cf ? cf : CONFIGFILE, "r");
        if (f) {
                r = 1;
                while ((get_line(&buffer, &len, f))) {
@@ -437,8 +513,8 @@ main(int argc, char **argv)
                if (r != 1)
                        goto abort;
        } else {
-               if (errno != ENOENT) {
-                       logger(LOG_ERR, "fopen `%s': %s", CONFIGFILE,
+               if (errno != ENOENT || cf) {
+                       logger(LOG_ERR, "fopen `%s': %s", cf ? cf : CONFIGFILE,
                                        strerror(errno));
                        goto abort;
                }
@@ -453,19 +529,11 @@ main(int argc, char **argv)
        add_reqmask(options->reqmask, DHCP_NTPSERVER);
 #endif
 
-       /* Don't set any optional arguments here so we retain POSIX
-        * compatibility with getopt */
-       while ((opt = getopt_long(argc, argv, EXTRA_OPTS
-                                 "c:dh:i:kl:m:no:pr:s:t:u:xAEF:GHI:LO:STV",
+       optind = 0;
+       while ((opt = getopt_long(argc, argv, OPTS EXTRA_OPTS,
                                  longopts, &option_index)) != -1)
        {
                switch (opt) {
-               case 0:
-                       if (longopts[option_index].flag)
-                               break;
-                       logger(LOG_ERR, "option `%s' should set a flag",
-                              longopts[option_index].name);
-                       goto abort;
                case 'd':
                        debug++;
                        switch (debug) {
@@ -477,12 +545,14 @@ main(int argc, char **argv)
                                        break;
                        }
                        break;
-#ifdef THERE_IS_NO_FORK
                case 'f':
+                       break;
+#ifdef THERE_IS_NO_FORK
+               case 'X':
                        options->options |= DHCPCD_DAEMONISED;
                        close_fds();
                        break;
-               case 'g':
+               case 'Z':
                        dhcpcd_skiproutes = xstrdup(optarg);
                        break;
 #endif
@@ -526,9 +596,6 @@ main(int argc, char **argv)
                        del_reqmask(options->reqmask, DHCP_NISDOMAIN);
                        break;
 #endif
-               case '?':
-                       usage();
-                       goto abort;
                default:
                        i = parse_option(opt, optarg, options);
                        if (i == 1)
@@ -538,57 +605,6 @@ main(int argc, char **argv)
                        goto abort;
                }
        }
-       if (doversion) {
-               printf(""PACKAGE" "VERSION"\n");
-               printf("Compile time options:"
-#ifdef ENABLE_ARP
-                       " ARP"
-#endif
-#ifdef ENABLE_DUID
-                       " DUID"
-#endif
-#ifdef ENABLE_IPV4LL
-                       " IPV4LL"
-#endif
-#ifdef THERE_IS_NO_FORK
-                       " THERE_IS_NO_FORK"
-#endif
-                       "\n");
-       }
-
-       if (dohelp)
-               usage();
-
-#ifdef THERE_IS_NO_FORK
-       dhcpcd_argv = argv;
-       dhcpcd_argc = argc;
-       if (!realpath(argv[0], dhcpcd)) {
-               logger(LOG_ERR, "unable to resolve the path `%s': %s",
-                      argv[0], strerror(errno));
-               goto abort;
-       }
-#endif
-
-       if (optind < argc) {
-               if (strlen(argv[optind]) > IF_NAMESIZE) {
-                       logger(LOG_ERR,
-                              "`%s' too long for an interface name (max=%d)",
-                              argv[optind], IF_NAMESIZE);
-                       goto abort;
-               }
-               strlcpy(options->interface, argv[optind],
-                       sizeof(options->interface));
-       } else {
-               /* If only version was requested then exit now */
-               if (doversion || dohelp) {
-                       retval = 0;
-                       goto abort;
-               }
-
-               logger(LOG_ERR, "no interface specified");
-               goto abort;
-       }
-
        if (strchr(options->hostname, '.')) {
                if (options->fqdn == FQDN_DISABLE)
                        options->fqdn = FQDN_BOTH;