diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2013-09-25 14:23:39 +0800 |
---|---|---|
committer | Jeremy Kerr <jk@ozlabs.org> | 2013-09-26 14:30:17 +0800 |
commit | ca5a62c1d04a3eea1d1c307d4fa4f0b1559140d2 (patch) | |
tree | 022367e0be0f9207dd4b7c4c87a3b85ea4717602 /discover/paths.c | |
parent | 7889b6f4bf81a1d2742c6f7d6fb9f6f603dd251e (diff) | |
download | talos-petitboot-ca5a62c1d04a3eea1d1c307d4fa4f0b1559140d2.tar.gz talos-petitboot-ca5a62c1d04a3eea1d1c307d4fa4f0b1559140d2.zip |
discover: Don't depend on tftp failure for type detection
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>
Diffstat (limited to 'discover/paths.c')
-rw-r--r-- | discover/paths.c | 109 |
1 files changed, 69 insertions, 40 deletions
diff --git a/discover/paths.c b/discover/paths.c index dbdf16e..82a82b1 100644 --- a/discover/paths.c +++ b/discover/paths.c @@ -186,6 +186,41 @@ fail: 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. * @@ -202,24 +237,44 @@ static char *load_tftp(void *ctx, struct pb_url *url, 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; - /* 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); @@ -237,32 +292,6 @@ static char *load_tftp(void *ctx, struct pb_url *url, 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; - talloc_free(local); return NULL; } |