X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Ffile.c;h=366d5ba9dbff93cf56c7a48c1dbcbbb230802bc2;hp=763e3e6ccd3761a90e5004d2975611511e51b9bd;hb=96f82eabe29d6d4039098d5320b3304acbedf67b;hpb=0ef1539b6f680ba09c88be5bb94a821fd2599931 diff --git a/second/file.c b/second/file.c index 763e3e6..366d5ba 100644 --- a/second/file.c +++ b/second/file.c @@ -33,33 +33,70 @@ extern char bootdevice[1024]; /* This function follows the device path in the devtree and separates the device name, partition number, and other datas (mostly file name) the string passed in parameters is changed since 0 are put in place - of some separators to terminate the various strings - */ + of some separators to terminate the various strings. + + when a default device is supplied imagepath will be assumed to be a + plain filename unless it contains a : otherwise if defaultdev is + NULL imagepath will be assumed to be a device path. + + returns 1 on success 0 on failure. + + Supported examples: + - /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:4 + - /pci@80000000/pci-bridge@d/ADPT,2930CU@2/@1:4,/boot/vmlinux + - hd:3,/boot/vmlinux + - enet:10.0.0.1,/tftpboot/vmlinux + - enet:,/tftpboot/vmlinux + - enet:bootp + - enet:0 + Supported only if defdevice == NULL + - disc + - any other device path lacking a : + Unsupported examples: + - hd:2,\\:tbxi <- no filename will be detected due to the extra : + - enet:192.168.2.1,bootme,c-iaddr,g-iaddr,subnet-mask,bootp-retries,tftp-retries */ int parse_device_path(char *imagepath, char *defdevice, int defpart, char *deffile, struct boot_fspec_t *result) { char *ptr; - char *ipath = strdup(imagepath); - char *defdev = strdup(defdevice); + char *ipath = NULL; + char *defdev = NULL; result->dev = NULL; result->part = -1; result->file = NULL; - if (!strstr(defdev, "ethernet") && !strstr(defdev, "enet")) { - if ((ptr = strrchr(defdev, ':')) != NULL) - *ptr = 0; /* remove trailing : from defdevice if necessary */ + if (!imagepath) + return 0; + else + ipath = strdup(imagepath); + + if (defdevice) + defdev = strdup(defdevice); + + if (defdev) { + if (!strstr(defdev, "ethernet") && !strstr(defdev, "enet")) { + if ((ptr = strrchr(defdev, ':')) != NULL) + *ptr = 0; /* remove trailing : from defdevice if necessary */ + } } - if (!imagepath) - goto punt; + /* if there is no : then there is no filename or partition. must + use strrchr() since enet:,10.0.0.1,file is legal */ - if ((ptr = strrchr(ipath, ',')) != NULL) { - result->file = strdup(ptr+1); - /* Trim the filename off */ - *ptr = 0; + if (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 (strstr(ipath, "ethernet") || strstr(ipath, "enet")) @@ -73,14 +110,15 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, 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 { return 0; } - -punt: - if (!result->dev) + + if (!result->dev && defdev) result->dev = strdup(defdev); if (result->part < 0) @@ -88,7 +126,10 @@ punt: if (!result->file) result->file = strdup(deffile); + free(ipath); + if (defdev) + free(defdev); return 1; } @@ -213,7 +254,7 @@ int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file) /* * Local variables: - * c-file-style: "K&R" + * c-file-style: "k&r" * c-basic-offset: 5 * End: */