+extern char bootdevice[];
+
+/*
+ * Copy the string from source to dest till newline or comma(,) is seen
+ * in the source.
+ * Move source and dest pointers respectively.
+ * Returns pointer to the start of the string that has just been copied.
+ */
+static char *
+scopy(char **dest, char **source)
+{
+ char *ret = *dest;
+
+ if (!**source)
+ return NULL;
+
+ while (**source != ',' && **source != '\0')
+ *(*dest)++ = *(*source)++;
+ if (**source != '\0')
+ *(*source)++;
+ **dest = '\0';
+ *(*dest)++;
+ return ret;
+}
+
+/*
+ * Extract all the arguments provided in the imagepath and fill it in result.
+ * Returns 1 on success, 0 on failure.
+ */
+static int
+extract_args_from_netdev_path(char *imagepath, struct boot_fspec_t *result)
+{
+ char *tmp, *args, *str, *start;
+
+ DEBUG_F("imagepath = %s\n", imagepath);
+
+ if (!imagepath)
+ return 1;
+
+ args = strrchr(imagepath, ':');
+ if (!args)
+ return 1;
+
+ start = args; /* used to see if we read any optional parameters */
+
+ /* The obp-tftp device arguments should be at the end of
+ * the argument list. Skip over any extra arguments (promiscuous,
+ * speed, duplex, bootp, rarp).
+ */
+
+ tmp = strstr(args, "promiscuous");
+ if (tmp && tmp > args)
+ args = tmp + strlen("promiscuous");
+
+ tmp = strstr(args, "speed=");
+ if (tmp && tmp > args)
+ args = tmp + strlen("speed=");
+
+ tmp = strstr(args, "duplex=");
+ if (tmp && tmp > args)
+ args = tmp + strlen("duplex=");
+
+ tmp = strstr(args, "bootp");
+ if (tmp && tmp > args)
+ args = tmp + strlen("bootp");
+
+ tmp = strstr(args, "rarp");
+ if (tmp && tmp > args)
+ args = tmp + strlen("rarp");
+
+ if (args != start) /* we read some parameters, so go past the next comma(,) */
+ args = strchr(args, ',');
+ if (!args)
+ return 1;
+
+ str = malloc(strlen(args) + 1); /*long enough to hold all strings */
+ if (!str)
+ return 0;
+
+ if (args[-1] != ':')
+ args++; /* If comma(,) is not immediately followed by ':' then go past the , */
+
+ /*
+ * read the arguments in order: siaddr,filename,ciaddr,giaddr,
+ * bootp-retries,tftp-retries,addl_prameters
+ */
+ result->siaddr = scopy(&str, &args);
+ result->file = scopy(&str, &args);
+ result->ciaddr = scopy(&str, &args);
+ result->giaddr = scopy(&str, &args);
+ result->bootp_retries = scopy(&str, &args);
+ result->tftp_retries = scopy(&str, &args);
+ if (*args) {
+ result->addl_params = strdup(args);
+ if (!result->addl_params)
+ return 0;
+ }
+
+ DEBUG_F("siaddr = <%s>\n", result->siaddr);
+ DEBUG_F("file = <%s>\n", result->file);
+ DEBUG_F("ciaddr = <%s>\n", result->ciaddr);
+ DEBUG_F("giaddr = <%s>\n", result->giaddr);
+ DEBUG_F("bootp_retries = <%s>\n", result->bootp_retries);
+ DEBUG_F("tftp_retries = <%s>\n", result->tftp_retries);
+ DEBUG_F("addl_params = <%s>\n", result->addl_params);
+ return 1;
+}
+
+static char *netdev_path_to_dev(const char *path)
+{
+ char *dev, *tmp;
+ size_t len;
+
+ DEBUG_F("path = %s\n", path);
+
+ if (!path)
+ return NULL;
+
+ tmp = strchr(path, ':');
+ if (!tmp)
+ return strdup(path);
+ tmp++;
+
+ len = tmp - path + 1;
+
+ dev = malloc(len);
+ if (dev) {
+ strncpy(dev, path, len);
+ dev[len - 1] = '\0';
+ }
+ return dev;
+}