+ char *ptr;
+ char *ipath = NULL;
+ char *defdev = NULL;
+ int device_kind = -1;
+
+ result->dev = NULL;
+ result->part = -1;
+ result->file = NULL;
+
+ if (!imagepath)
+ return 0;
+
+ /*
+ * Do preliminary checking for an iscsi device; it may appear as
+ * pure a network device (device_type == "network") if this is
+ * ISWI. This is the case on IBM systems doing an iscsi OFW
+ * boot.
+ */
+ if (strstr(imagepath, TOK_ISCSI)) {
+ /*
+ * get the virtual device information from the
+ * "nas-bootdevice" property.
+ */
+ if (prom_get_chosen("nas-bootdevice", bootdevice, BOOTDEVSZ)) {
+ DEBUG_F("reset boot-device to"
+ " /chosen/nas-bootdevice = %s\n", bootdevice);
+ device_kind = FILE_DEVICE_ISCSI;
+ ipath = strdup(bootdevice);
+ if (!ipath)
+ return 0;
+ }
+ else
+ return 0;
+ }
+ else if (!(ipath = strdup(imagepath)))
+ return 0;
+
+ if (defdevice) {
+ defdev = strdup(defdevice);
+ device_kind = prom_get_devtype(defdev);
+ } else if (device_kind == -1)
+ device_kind = prom_get_devtype(ipath);
+
+ /*
+ * When an iscsi iqn is present, it may have embedded colons, so
+ * don't parse off anything.
+ */
+ if (device_kind != FILE_DEVICE_NET &&
+ device_kind != FILE_DEVICE_ISCSI &&
+ strchr(defdev, ':') != NULL) {
+ if ((ptr = strrchr(defdev, ':')) != NULL)
+ *ptr = 0; /* remove trailing : from defdevice if necessary */
+ }
+
+ /* This will not properly handle an obp-tftp argument list
+ * with elements after the filename; that is handled below.
+ */
+ if (device_kind != FILE_DEVICE_NET &&
+ device_kind != FILE_DEVICE_ISCSI &&
+ strchr(ipath, ':') != NULL) {
+ if ((ptr = strrchr(ipath, ',')) != NULL) {
+ char *colon = strrchr(ipath, ':');
+ /* If a ':' occurs *after* a ',', then we assume that there is
+ no filename */
+ if (!colon || colon < ptr) {
+ result->file = strdup(ptr+1);
+ /* Trim the filename off */
+ *ptr = 0;
+ }
+ }
+ }
+
+ if (device_kind == FILE_DEVICE_NET) {
+ if (strchr(ipath, ':'))
+ result->file = netdev_path_to_filename(ipath);
+ else
+ result->file = strdup(ipath);
+
+ if (!defdev)
+ result->dev = netdev_path_to_dev(ipath);
+ } else if (device_kind != FILE_DEVICE_ISCSI &&
+ (ptr = strrchr(ipath, ':')) != NULL) {
+ *ptr = 0;
+ result->dev = strdup(ipath);
+ if (*(ptr+1))
+ result->part = simple_strtol(ptr+1, NULL, 10);
+ } else if (!defdev) {
+ result->dev = strdup(ipath);
+ } else if (strlen(ipath)) {
+ result->file = strdup(ipath);
+ } else {
+ free(defdev);
+ return 0;
+ }
+
+ if (!result->dev && defdev)
+ result->dev = strdup(defdev);
+
+ if (result->part < 0)
+ result->part = defpart;
+
+ if (!result->file)
+ result->file = strdup(deffile);
+
+ free(ipath);
+ if (defdev)
+ free(defdev);
+ return 1;