X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Ffile.c;h=366d5ba9dbff93cf56c7a48c1dbcbbb230802bc2;hp=712222caf83b4fcfdee80fc458e690b92cee77a4;hb=96f82eabe29d6d4039098d5320b3304acbedf67b;hpb=5613f9fab88b71f14259856b390f1cc989b602bf diff --git a/second/file.c b/second/file.c index 712222c..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")) @@ -67,20 +104,21 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, *ptr = 0; result->dev = strdup(ipath); } else - result->dev = strdup(ipath); + result->dev = strdup(ipath); else if ((ptr = strchr(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 { return 0; } - - punt: - if (!result->dev) + + if (!result->dev && defdev) result->dev = strdup(defdev); if (result->part < 0) @@ -88,7 +126,10 @@ parse_device_path(char *imagepath, char *defdevice, int defpart, if (!result->file) result->file = strdup(deffile); + free(ipath); + if (defdev) + free(defdev); return 1; } @@ -99,46 +140,46 @@ file_block_open( struct boot_file_t* file, const char* file_name, int partition) { - struct partition_t* parts; - struct partition_t* p; - struct partition_t* found; + struct partition_t* parts; + struct partition_t* p; + struct partition_t* found; - parts = partitions_lookup(dev_name); - found = NULL; + parts = partitions_lookup(dev_name); + found = NULL; #if DEBUG - if (parts) - prom_printf("partitions:\n"); - else - prom_printf("no partitions found.\n"); + if (parts) + prom_printf("partitions:\n"); + else + prom_printf("no partitions found.\n"); #endif - for (p = parts; p && !found; p=p->next) { - DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n", - p->part_number, p->part_start, p->part_size ); - if (partition == -1) { - file->fs = fs_open( file, dev_name, p, file_name ); - if (file->fs != NULL) - goto bail; - } - if ((partition >= 0) && (partition == p->part_number)) - found = p; + for (p = parts; p && !found; p=p->next) { + DEBUG_F("number: %02d, start: 0x%08lx, length: 0x%08lx\n", + p->part_number, p->part_start, p->part_size ); + if (partition == -1) { + file->fs = fs_open( file, dev_name, p, file_name ); + if (file->fs != NULL) + goto bail; + } + if ((partition >= 0) && (partition == p->part_number)) + found = p; #if DEBUG - if (found) - prom_printf(" (match)\n"); + if (found) + prom_printf(" (match)\n"); #endif - } + } - /* Note: we don't skip when found is NULL since we can, in some - * cases, let OF figure out a default partition. - */ - DEBUG_F( "Using OF defaults.. (found = %p)\n", found ); - file->fs = fs_open( file, dev_name, found, file_name ); + /* Note: we don't skip when found is NULL since we can, in some + * cases, let OF figure out a default partition. + */ + DEBUG_F( "Using OF defaults.. (found = %p)\n", found ); + file->fs = fs_open( file, dev_name, found, file_name ); bail: - if (parts) - partitions_free(parts); + if (parts) + partitions_free(parts); - return fserrorno; + return fserrorno; } static int @@ -146,8 +187,8 @@ file_net_open( struct boot_file_t* file, const char* dev_name, const char* file_name) { - file->fs = fs_of_netboot; - return fs_of_netboot->open(file, dev_name, NULL, file_name); + file->fs = fs_of_netboot; + return fs_of_netboot->open(file, dev_name, NULL, file_name); } static int @@ -155,65 +196,65 @@ default_read( struct boot_file_t* file, unsigned int size, void* buffer) { - prom_printf("WARNING ! default_read called !\n"); - return FILE_ERR_EOF; + prom_printf("WARNING ! default_read called !\n"); + return FILE_ERR_EOF; } static int default_seek( struct boot_file_t* file, unsigned int newpos) { - prom_printf("WARNING ! default_seek called !\n"); - return FILE_ERR_EOF; + prom_printf("WARNING ! default_seek called !\n"); + return FILE_ERR_EOF; } static int default_close( struct boot_file_t* file) { - prom_printf("WARNING ! default_close called !\n"); - return FILE_ERR_OK; + prom_printf("WARNING ! default_close called !\n"); + return FILE_ERR_OK; } static struct fs_t fs_default = { - "defaults", - NULL, - default_read, - default_seek, - default_close + "defaults", + NULL, + default_read, + default_seek, + default_close }; int open_file(const struct boot_fspec_t* spec, struct boot_file_t* file) { - int result; + int result; - memset(file, 0, sizeof(struct boot_file_t*)); - file->fs = &fs_default; + memset(file, 0, sizeof(struct boot_file_t*)); + file->fs = &fs_default; - DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n", - spec->dev, spec->file, spec->part); + DEBUG_F("dev_path = %s\nfile_name = %s\npartition = %d\n", + spec->dev, spec->file, spec->part); - result = prom_get_devtype(spec->dev); - if (result > 0) - file->device_kind = result; - else - return result; + result = prom_get_devtype(spec->dev); + if (result > 0) + file->device_kind = result; + else + return result; - switch(file->device_kind) { - case FILE_DEVICE_BLOCK: - DEBUG_F("device is a block device\n"); - return file_block_open(file, spec->dev, spec->file, spec->part); - case FILE_DEVICE_NET: - DEBUG_F("device is a network device\n"); - return file_net_open(file, spec->dev, spec->file); - } - return 0; + switch(file->device_kind) { + case FILE_DEVICE_BLOCK: + DEBUG_F("device is a block device\n"); + return file_block_open(file, spec->dev, spec->file, spec->part); + case FILE_DEVICE_NET: + DEBUG_F("device is a network device\n"); + return file_net_open(file, spec->dev, spec->file); + } + return 0; } /* * Local variables: - * c-file-style: "K&R" + * c-file-style: "k&r" * c-basic-offset: 5 * End: */