libupload: don't error out because the tftp functions are unavailable

Provide weak stubs for the case where the tftp functions aren't
available.  This prevents link failures for the case of running on top
of non-network cores.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
diff --git a/com32/libupload/tftp.h b/com32/libupload/tftp.h
index 323dc16..209d975 100644
--- a/com32/libupload/tftp.h
+++ b/com32/libupload/tftp.h
@@ -2,7 +2,8 @@
 
 #ifndef UPLOAD_TFTP
 #define UPLOAD_TFTP
-/* TFTP Error codes */
+
+/* TFTP Error codes in host byte order */
 enum tftp_error_codes {
 TFTP_ERR_UNKNOWN_ERROR = 0, // We have to use the message from the server
 TFTP_ERR_FILE_NOT_FOUND	= 1, /**< File not found */
@@ -13,9 +14,12 @@
 TFTP_ERR_FILE_EXISTS = 6, /**< File already exists */
 TFTP_ERR_UNKNOWN_USER = 7, /**< No such user */
 TFTP_ERR_BAD_OPTS = 8, /**< Option negotiation failed */
-TFTP_ERR_UNABLE_TO_RESOLVE = 9, // Not in RFC, internal usage 
-TFTP_ERR_UNABLE_TO_CONNECT = 10, // Not in RFC, internal usage
-TFTP_OK	= 11, /* Not in RFC */
+
+/* The following are not defined in RFC, for internal usage only */
+TFTP_ERR_UNABLE_TO_RESOLVE = 9,
+TFTP_ERR_UNABLE_TO_CONNECT = 10,
+TFTP_ERR_OK = 11,
+TFTP_ERR_NO_NETWORK = 12,
 };
 
 extern const char *tftp_string_error_message[];
diff --git a/com32/libupload/upload_tftp.c b/com32/libupload/upload_tftp.c
index 387113b..80fe0bf 100644
--- a/com32/libupload/upload_tftp.c
+++ b/com32/libupload/upload_tftp.c
@@ -10,23 +10,29 @@
 #include <sys/times.h>
 #include <fs/pxe/pxe.h>
 #include <fs/pxe/url.h>
+#include <fs/pxe/tftp.h>
 #include "upload_backend.h"
 
 const char *tftp_string_error_message[]={
-"Unknown error",
-"File not found",
-"Access Denied",
-"Disk Full",
-"Illegal Operation",
-"Unknown Transfert ID",
-"File already exists",
-"Unknown User",
-"Negociation failed",
-"Unable to resolve hostname", // not in RFC
-"Unable to connect", // not in RFC
-"No Error",
+    "Unknown error",
+    "File not found",
+    "Access Denied",
+    "Disk Full",
+    "Illegal Operation",
+    "Unknown Transfer ID",
+    "File already exists",
+    "Unknown User",
+    "Negotiation failed",
+
+    /* These are not in any RFC, defined internally */
+    "Unable to resolve hostname",
+    "Unable to connect",
+    "No Error",
+    "Network unavailable",
 };
 
+static bool have_real_network(void);
+
 static int upload_tftp_write(struct upload_backend *be) {
     const union syslinux_derivative_info *sdi =
 	syslinux_derivative_info();
@@ -36,6 +42,11 @@
     uint32_t ip;
     int err;
 
+    if (!have_real_network()) {
+	dprintf("\nNot running from the network\n");
+	return -TFTP_ERR_NO_NETWORK;
+    }
+
     if (be->argv[1]) {
         ip = pxe_dns(be->argv[1]);
         if (!ip) {
@@ -75,3 +86,46 @@
     .minargs    = 1,
     .write      = upload_tftp_write,
 };
+
+/*
+ * Dummy functions to prevent link failure for non-network cores
+ */
+static int _dummy_tftp_put(struct url_info *url, int flags,
+			   struct inode *inode, const char **redir,
+			   char *data, int data_length)
+{
+    (void)url;
+    (void)flags;
+    (void)inode;
+    (void)redir;
+    (void)data;
+    (void)data_length;
+
+    return -TFTP_ERR_NO_NETWORK;
+}
+
+__weak int __attribute__((alias("_dummy_tftp_put")))
+tftp_put(struct url_info *url, int flags, struct inode *inode,
+	 const char **redir, char *data, int data_length);
+
+static int _dummy_tftp_put(struct url_info *url, int flags,
+			   struct inode *inode, const char **redir,
+			   char *data, int data_length);
+
+static bool have_real_network(void)
+{
+    return tftp_put != _dummy_tftp_put;
+}
+
+__weak uint32_t dns_resolv(const char *host)
+{
+    (void)host;
+
+    return 0;
+}
+
+__weak void parse_url(struct url_info *ui, char *url)
+{
+    (void)ui;
+    (void)url;
+}
diff --git a/core/fs/pxe/tftp.h b/core/fs/pxe/tftp.h
index 8802914..82ef64a 100644
--- a/core/fs/pxe/tftp.h
+++ b/core/fs/pxe/tftp.h
@@ -53,6 +53,7 @@
 #define TFTP_ERESOLVE	 htons(9)		// Not in RFC, internal usage
 #define TFTP_ECONNECT	 htons(10)		// Not in RFC, internal usage
 #define TFTP_OK	 	 htons(11)		// Not in RFC, internal usage
+#define TFTP_NONETWORK   htons(12)              // Not in RFC, internal usage
 
 struct tftp_error {
         uint16_t opcode;
@@ -61,5 +62,6 @@
 } __attribute__ (( packed ));
 
 int tftp_put(struct url_info *url, int flags, struct inode *inode,
-		               const char **redir, char *data, int data_length);
+	     const char **redir, char *data, int data_length);
+
 #endif /* PXE_TFTP_H */