]> git.ozlabs.org Git - petitboot/commitdiff
discover: Don't depend on tftp failure for type detection
authorJeremy Kerr <jk@ozlabs.org>
Wed, 25 Sep 2013 06:23:39 +0000 (14:23 +0800)
committerJeremy Kerr <jk@ozlabs.org>
Thu, 26 Sep 2013 06:30:17 +0000 (14:30 +0800)
Rather than always trying both TFTP client types, do a runtime detection
on first invocation. This can be fixed at build-time with
--with-tftp=TYPE.

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
configure.ac.in
discover/paths.c
lib/system/system.c
lib/system/system.h

index 7f13cca4db96b050bc9951bbc3a36920703e1b55..3374a9a945989bb503c0a8a9eedbb850d64d952c 100644 (file)
@@ -205,6 +205,29 @@ DEFINE_HOST_PROG(WGET, wget, [/usr/bin/wget])
 DEFINE_HOST_PROG(IP, ip, [/sbin/ip])
 DEFINE_HOST_PROG(UDHCPC, udhcpc, [/sbin/udhcpc])
 
 DEFINE_HOST_PROG(IP, ip, [/sbin/ip])
 DEFINE_HOST_PROG(UDHCPC, udhcpc, [/sbin/udhcpc])
 
+AC_ARG_WITH(
+    [tftp],
+    [AS_HELP_STRING([--with-tftp=TYPE],
+        [Use TYPE-type ftp client (either hpa or busybox) [default=runtime-check]]
+    )],
+    [],
+    [with_tftp=detect]
+)
+
+case x$with_tftp in
+'xhpa')
+    tftp_type='TFTP_TYPE_HPA'
+    ;;
+'xbusybox')
+    tftp_type='TFTP_TYPE_BUSYBOX'
+    ;;
+*)
+    tftp_type='TFTP_TYPE_UNKNOWN'
+    ;;
+esac
+
+AC_DEFINE_UNQUOTED(TFTP_TYPE, $tftp_type, [tftp client type])
+
 default_cflags="--std=gnu99 -g \
        -Wall -W -Wunused -Wstrict-prototypes -Wmissing-prototypes \
        -Wmissing-declarations -Wredundant-decls"
 default_cflags="--std=gnu99 -g \
        -Wall -W -Wunused -Wstrict-prototypes -Wmissing-prototypes \
        -Wmissing-declarations -Wredundant-decls"
index dbdf16e51628fc0cf9a8725ae2f422ee7e6db549..82a82b15125c7b2317d8d95d54fc784783af8d01 100644 (file)
@@ -186,6 +186,41 @@ fail:
        return NULL;
 }
 
        return NULL;
 }
 
+static enum tftp_type check_tftp_type(void *ctx)
+{
+       const char *argv[] = { pb_system_apps.tftp, "-V", NULL };
+       struct process *process;
+       enum tftp_type type;
+
+       process = process_create(ctx);
+       process->path = pb_system_apps.tftp;
+       process->argv = argv;
+       process->keep_stdout = true;
+       process_run_sync(process);
+
+       if (!process->stdout_buf || process->stdout_len == 0) {
+               pb_log("Can't check TFTP client type!\n");
+               type = TFTP_TYPE_BROKEN;
+
+       } else if (memmem(process->stdout_buf, process->stdout_len,
+                               "tftp-hpa", strlen("tftp-hpa"))) {
+               pb_debug("Found TFTP client type: tftp-hpa\n");
+               type = TFTP_TYPE_HPA;
+
+       } else if (memmem(process->stdout_buf, process->stdout_len,
+                               "BusyBox", strlen("BusyBox"))) {
+               pb_debug("Found TFTP client type: BusyBox tftp\n");
+               type = TFTP_TYPE_BUSYBOX;
+
+       } else {
+               pb_log("Unknown TFTP client type!\n");
+               type = TFTP_TYPE_BROKEN;
+       }
+
+       process_release(process);
+       return type;
+}
+
 /**
  * pb_load_tftp - Loads a remote file via tftp and returns the local file path.
  *
 /**
  * pb_load_tftp - Loads a remote file via tftp and returns the local file path.
  *
@@ -202,24 +237,44 @@ static char *load_tftp(void *ctx, struct pb_url *url,
        char *local;
        struct process *process;
 
        char *local;
        struct process *process;
 
-       local = local_name(ctx);
+       if (tftp_type == TFTP_TYPE_UNKNOWN)
+               tftp_type = check_tftp_type(ctx);
 
 
-       if (!local)
+       if (tftp_type == TFTP_TYPE_BROKEN)
                return NULL;
 
                return NULL;
 
-       /* first try busybox tftp args */
+       local = local_name(ctx);
+       if (!local)
+               return NULL;
 
 
-       p = argv;
-       *p++ = pb_system_apps.tftp;     /* 1 */
-       *p++ = "-g";                    /* 2 */
-       *p++ = "-l";                    /* 3 */
-       *p++ = local;                   /* 4 */
-       *p++ = "-r";                    /* 5 */
-       *p++ = url->path;               /* 6 */
-       *p++ = url->host;               /* 7 */
-       if (url->port)
-               *p++ = url->port;       /* 8 */
-       *p++ = NULL;                    /* 9 */
+       if (tftp_type == TFTP_TYPE_BUSYBOX) {
+               /* first try busybox tftp args */
+
+               p = argv;
+               *p++ = pb_system_apps.tftp;     /* 1 */
+               *p++ = "-g";                    /* 2 */
+               *p++ = "-l";                    /* 3 */
+               *p++ = local;                   /* 4 */
+               *p++ = "-r";                    /* 5 */
+               *p++ = url->path;               /* 6 */
+               *p++ = url->host;               /* 7 */
+               if (url->port)
+                       *p++ = url->port;       /* 8 */
+               *p++ = NULL;                    /* 9 */
+       } else {
+               p = argv;
+               *p++ = pb_system_apps.tftp;     /* 1 */
+               *p++ = "-m";                    /* 2 */
+               *p++ = "binary";                /* 3 */
+               *p++ = url->host;               /* 4 */
+               if (url->port)
+                       *p++ = url->port;       /* 5 */
+               *p++ = "-c";                    /* 6 */
+               *p++ = "get";                   /* 7 */
+               *p++ = url->path;               /* 8 */
+               *p++ = local;                   /* 9 */
+               *p++ = NULL;                    /* 10 */
+       }
 
        if (url_data) {
                process = process_create(ctx);
 
        if (url_data) {
                process = process_create(ctx);
@@ -234,32 +289,6 @@ static char *load_tftp(void *ctx, struct pb_url *url,
                result = process_run_simple_argv(ctx, argv);
        }
 
                result = process_run_simple_argv(ctx, argv);
        }
 
-       if (!result)
-               return local;
-
-       /* next try tftp-hpa args */
-       p = argv;
-       *p++ = pb_system_apps.tftp;     /* 1 */
-       *p++ = "-m";                    /* 2 */
-       *p++ = "binary";                /* 3 */
-       *p++ = url->host;               /* 4 */
-       if (url->port)
-               *p++ = url->port;       /* 5 */
-       *p++ = "-c";                    /* 6 */
-       *p++ = "get";                   /* 7 */
-       *p++ = url->path;               /* 8 */
-       *p++ = local;                   /* 9 */
-       *p++ = NULL;                    /* 10 */
-
-       if (url_data) {
-               process->argv = argv;
-               result = process_run_async(process);
-               if (result)
-                       process_release(process);
-       } else {
-               result = process_run_simple_argv(ctx, argv);
-       }
-
        if (!result)
                return local;
 
        if (!result)
                return local;
 
index 6e80b24ec1eaac9176629af6799f292546c668a1..c9fe979465239d589d5db35de8c57ed75643949e 100644 (file)
@@ -30,6 +30,12 @@ const struct pb_system_apps pb_system_apps = {
        .udhcpc         = HOST_PROG_UDHCPC,
 };
 
        .udhcpc         = HOST_PROG_UDHCPC,
 };
 
+#ifndef TFTP_TYPE
+#define TFTP_TYPE TFTP_TYPE_UNKNOWN
+#endif
+
+enum tftp_type tftp_type = TFTP_TYPE;
+
 int pb_mkdir_recursive(const char *dir)
 {
        struct stat statbuf;
 int pb_mkdir_recursive(const char *dir)
 {
        struct stat statbuf;
index 271c4355d3066cb46c10fe224abd65fa277f82b8..ab251016a4caf44282683f1adfc6a24d6e3c233c 100644 (file)
@@ -17,6 +17,15 @@ struct pb_system_apps {
 
 extern const struct pb_system_apps pb_system_apps;
 
 
 extern const struct pb_system_apps pb_system_apps;
 
+enum tftp_type {
+       TFTP_TYPE_BUSYBOX,
+       TFTP_TYPE_HPA,
+       TFTP_TYPE_UNKNOWN,
+       TFTP_TYPE_BROKEN,
+};
+
+extern enum tftp_type tftp_type;
+
 int pb_run_cmd(const char *const *cmd_argv, int wait, int dry_run);
 int pb_mkdir_recursive(const char *dir);
 int pb_rmdir_recursive(const char *base, const char *dir);
 int pb_run_cmd(const char *const *cmd_argv, int wait, int dry_run);
 int pb_mkdir_recursive(const char *dir);
 int pb_rmdir_recursive(const char *base, const char *dir);