/* Put the label in *label and uuid in *uuid. * Return 0 if no label/uuid found, NZ if there is a label or uuid. */ int find_label_or_uuid(char *dev_name, char *label, char *uuid) { struct volume_id id; memset(&id, 0x00, sizeof(id)); if (label) *label = 0; if (uuid) *uuid = 0; if ((id.fd = open(dev_name, O_RDONLY)) < 0) return 0; volume_id_get_buffer(&id, 0, SB_BUFFER_SIZE); if (volume_id_probe_linux_swap(&id) == 0 || id.error) goto ret; if (volume_id_probe_vfat(&id) == 0 || id.error) goto ret; if (volume_id_probe_ext(&id) == 0 || id.error) goto ret; if (volume_id_probe_ntfs(&id) == 0 || id.error) goto ret; #if defined(RTCONFIG_HFS) if(volume_id_probe_hfs_hfsplus(&id) == 0 || id.error) goto ret; #endif ret: volume_id_free_buffer(&id); if (label && (*id.label != 0)) strcpy(label, id.label); if (uuid && (*id.uuid != 0)) strcpy(uuid, id.uuid); close(id.fd); return (label && *label != 0) || (uuid && *uuid != 0); }
int find_partition_label(const char *dev_name, char *label){ struct volume_id id; char dev_path[128]; memset(dev_path, 0, 128); sprintf(dev_path, "/dev/%s", dev_name); memset(&id, 0x00, sizeof(id)); if((id.fd = open(dev_path, O_RDONLY)) < 0) return 0; if(label) *label = 0; volume_id_get_buffer(&id, 0, SB_BUFFER_SIZE); if(volume_id_probe_linux_swap(&id) == 0 || id.error) goto ret; if(volume_id_probe_ext(&id) == 0 || id.error) goto ret; if(volume_id_probe_vfat(&id) == 0 || id.error) goto ret; if(volume_id_probe_ntfs(&id) == 0 || id.error) goto ret; ret: volume_id_free_buffer(&id); if(label && (*id.label != 0)) strcpy(label, id.label); close(id.fd); return (label && *label != 0); }
/** * volume_id_probe_raid: * @id: Probing context. * @off: Probing offset relative to the start of the device. * @size: Total size of the device. * * Probe device for all known raid signatures. * * Returns: 0 on successful probe, otherwise negative value. **/ int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) { unsigned int i; if (id == NULL) return -EINVAL; if (!device_is_readable(id, off)) return -1; info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size); for (i = 0; i < ARRAY_SIZE(prober_raid); i++) { if (prober_raid[i].prober(id, off, size) == 0) { info("signature '%s' detected\n", id->type); goto found; } } return -1; found: /* If recognized, we free the allocated buffers */ volume_id_free_buffer(id); return 0; }
/** * volume_id_close: * @id: Probing context. * * Release probing context and free all associated data. */ void volume_id_close(struct volume_id *id) { if (id == NULL) return; volume_id_free_buffer(id); free(id); }
int find_partition_label(const char *dev_name, char *label, int partition_order) { struct volume_id id; char dev_path[128]; char usb_port[8]; int port_num; char nvram_label[32], nvram_value[512]; if(label) *label = 0; memset(usb_port, 0, 8); if(get_usb_port_by_device(dev_name, usb_port, 8) == NULL) return 0; port_num = get_usb_port_number(usb_port); memset(nvram_label, 0, 32); sprintf(nvram_label, "usb_path%d_label%d", port_num, partition_order); memset(nvram_value, 0, 512); strncpy(nvram_value, nvram_safe_get(nvram_label), 512); if(strlen(nvram_value) > 0) { strcpy(label, nvram_value); return (label && *label != 0); } memset(dev_path, 0, 128); sprintf(dev_path, "/dev/%s", dev_name); memset(&id, 0x00, sizeof(id)); if((id.fd = open(dev_path, O_RDONLY)) < 0) return 0; volume_id_get_buffer(&id, 0, SB_BUFFER_SIZE); if(volume_id_probe_linux_swap(&id) == 0 || id.error) goto ret; if(volume_id_probe_ext(&id) == 0 || id.error) goto ret; if(volume_id_probe_vfat(&id) == 0 || id.error) goto ret; if(volume_id_probe_ntfs(&id) == 0 || id.error) goto ret; if(volume_id_probe_hfs_hfsplus(&id) == 0 || id.error) goto ret; ret: volume_id_free_buffer(&id); if(label && (*id.label != 0)) strcpy(label, id.label); else strcpy(label, " "); nvram_set(nvram_label, label); close(id.fd); return (label && *label != 0); }
void FAST_FUNC free_volume_id(struct volume_id *id) { if (id == NULL) return; //if (id->fd_close != 0) - always true close(id->fd); volume_id_free_buffer(id); #ifdef UNUSED_PARTITION_CODE free(id->partitions); #endif free(id); }
int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64_t size) { unsigned i, arsize; /* probe for raid first, cause fs probes may be successful on raid members */ if (size) { arsize=ARRAY_SIZE(raid1); for (i = 0; i < arsize; i++) { if (raid1[i](id, /*off,*/ size) == 0) goto ret; if (id->error) goto ret; } } arsize=ARRAY_SIZE(raid2); for (i = 0; i < arsize; i++) { if (raid2[i](id /*,off*/) == 0) goto ret; if (id->error) goto ret; } /* signature in the first block, only small buffer needed */ arsize=ARRAY_SIZE(fs1); for (i = 0; i < arsize; i++) { if (fs1[i](id /*,off*/) == 0) goto ret; if (id->error) goto ret; } /* fill buffer with maximum */ volume_id_get_buffer(id, 0, SB_BUFFER_SIZE); arsize=ARRAY_SIZE(fs2); for (i = 0; i < arsize; i++) { if (fs2[i](id /*,off*/) == 0) break; if (id->error) break; } volume_id_free_buffer(id); ret: return (- id->error); /* 0 or -1 */ }
int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) { unsigned i; if (id == NULL) return -EINVAL; /* probe for raid first, cause fs probes may be successful on raid members */ if (size) { for (i = 0; i < ARRAY_SIZE(raid1); i++) if (raid1[i](id, off, size) == 0) goto ret; } for (i = 0; i < ARRAY_SIZE(raid2); i++) if (raid2[i](id, off) == 0) goto ret; /* signature in the first block, only small buffer needed */ for (i = 0; i < ARRAY_SIZE(fs1); i++) if (fs1[i](id, off) == 0) goto ret; /* fill buffer with maximum */ volume_id_get_buffer(id, 0, SB_BUFFER_SIZE); for (i = 0; i < ARRAY_SIZE(fs2); i++) if (fs2[i](id, off) == 0) goto ret; return -1; ret: /* If the filestystem in recognized, we free the allocated buffers, otherwise they will stay in place for the possible next probe call */ volume_id_free_buffer(id); return 0; }
/** * volume_id_probe_filesystem: * @id: Probing context. * @off: Probing offset relative to the start of the device. * @size: Total size of the device. * * Probe device for all known filesystem signatures. * * Returns: 0 on successful probe, otherwise negative value. **/ int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) { unsigned int i; if (id == NULL) return -EINVAL; if (!device_is_readable(id, off)) return -1; info("probing at offset 0x%" PRIx64 ", size 0x%" PRIx64 "\n", off, size); /* * We probe for all known filesystems to find conflicting signatures. If * we find multiple matching signatures and one of the detected filesystem * types claims that it can not co-exist with any other filesystem type, * we do not return a probing result. * * We can not afford to mount a volume with the wrong filesystem code and * possibly corrupt it. Linux sytems have the problem of dozens of possible * filesystem types, and volumes with left-over signatures from former * filesystem types. Invalid signatures need to be removed from the volume * to make the filesystem detection successful. * * We do not want to read that many bytes from probed floppies, skip volumes * smaller than a usual floppy disk. */ if (size > 1440 * 1024) { int found = 0; int force_unique_result = 0; int first_match = -1; volume_id_reset_result(id); for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) { int match; match = (prober_filesystem[i].prober(id, off, size) == 0); if (match) { info("signature '%s' %i detected\n", id->type, i); if (id->force_unique_result) force_unique_result = 1; if (found > 0 && force_unique_result) { info("conflicting signatures found, skip results\n"); return -1; } found++; if (first_match < 0) first_match = i; } } if (found < 1) return -1; if (found == 1) goto found; if (found > 1) { volume_id_reset_result(id); info("re-read first match metadata %i\n", first_match); if (prober_filesystem[first_match].prober(id, off, size) == 0) goto found; return -1; } } /* return the first match */ volume_id_reset_result(id); for (i = 0; i < ARRAY_SIZE(prober_filesystem); i++) { if (prober_filesystem[i].prober(id, off, size) == 0) { info("signature '%s' detected\n", id->type); goto found; } } return -1; found: /* If recognized, we free the allocated buffers */ volume_id_free_buffer(id); return 0; }