static int probe_superblocks(blkid_probe pr) { struct stat st; int rc; if (fstat(blkid_probe_get_fd(pr), &st)) return -1; blkid_probe_enable_partitions(pr, 1); if (!S_ISCHR(st.st_mode) && blkid_probe_get_size(pr) <= 1024 * 1440 && blkid_probe_is_wholedisk(pr)) { /* * check if the small disk is partitioned, if yes then * don't probe for filesystems. */ blkid_probe_enable_superblocks(pr, 0); rc = blkid_do_fullprobe(pr); if (rc < 0) return rc; /* -1 = error, 1 = nothing, 0 = success */ if (blkid_probe_lookup_value(pr, "PTTYPE", NULL, NULL) == 0) return 0; /* partition table detected */ } blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS); blkid_probe_enable_superblocks(pr, 1); return blkid_do_safeprobe(pr); }
static int probe_viaraid(blkid_probe pr, const struct blkid_idmag *mag) { uint64_t off; struct via_metadata *v; if (pr->size < 0x10000) return -1; if (!S_ISREG(pr->mode) && !blkid_probe_is_wholedisk(pr)) return -1; off = ((pr->size / 0x200)-1) * 0x200; v = (struct via_metadata *) blkid_probe_get_buffer(pr, off, sizeof(struct via_metadata)); if (!v) return -1; if (le16_to_cpu(v->signature) != VIA_SIGNATURE) return -1; if (v->version_number > 2) return -1; if (!via_checksum(v)) return -1; if (blkid_probe_sprintf_version(pr, "%u", v->version_number) != 0) return -1; if (blkid_probe_set_magic(pr, off, sizeof(v->signature), (unsigned char *) &v->signature)) return -1; return 0; }
static void blkid_fill_info(struct device_info *info, blkid_probe pr) { blkid_partlist plist; if (device_info_verbose >= 3) printf("blkid_fill_info()\n"); if (blkid_probe_is_wholedisk(pr)) info->partition = 0; else info->partition = 1; plist = blkid_probe_get_partitions(pr); if (plist && blkid_partlist_numof_partitions(plist)) info->has_children = 1; }
static int fat_valid_superblock(blkid_probe pr, const struct blkid_idmag *mag, struct msdos_super_block *ms, struct vfat_super_block *vs, uint32_t *cluster_count, uint32_t *fat_size) { uint16_t sector_size, dir_entries, reserved; uint32_t sect_count, __fat_size, dir_size, __cluster_count, fat_length; uint32_t max_count; /* extra check for FATs without magic strings */ if (mag->len <= 2) { /* Old floppies have a valid MBR signature */ if (ms->ms_pmagic[0] != 0x55 || ms->ms_pmagic[1] != 0xAA) return 0; /* * OS/2 and apparently DFSee will place a FAT12/16-like * pseudo-superblock in the first 512 bytes of non-FAT * filesystems --- at least JFS and HPFS, and possibly others. * So we explicitly check for those filesystems at the * FAT12/16 filesystem magic field identifier, and if they are * present, we rule this out as a FAT filesystem, despite the * FAT-like pseudo-header. */ if ((memcmp(ms->ms_magic, "JFS ", 8) == 0) || (memcmp(ms->ms_magic, "HPFS ", 8) == 0)) return 0; } /* fat counts(Linux kernel expects at least 1 FAT table) */ if (!ms->ms_fats) return 0; if (!ms->ms_reserved) return 0; if (!(0xf8 <= ms->ms_media || ms->ms_media == 0xf0)) return 0; if (!is_power_of_2(ms->ms_cluster_size)) return 0; sector_size = unaligned_le16(&ms->ms_sector_size); if (!is_power_of_2(sector_size) || sector_size < 512 || sector_size > 4096) return 0; dir_entries = unaligned_le16(&ms->ms_dir_entries); reserved = le16_to_cpu(ms->ms_reserved); sect_count = unaligned_le16(&ms->ms_sectors); if (sect_count == 0) sect_count = le32_to_cpu(ms->ms_total_sect); fat_length = le16_to_cpu(ms->ms_fat_length); if (fat_length == 0) fat_length = le32_to_cpu(vs->vs_fat32_length); __fat_size = fat_length * ms->ms_fats; dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + (sector_size-1)) / sector_size; __cluster_count = (sect_count - (reserved + __fat_size + dir_size)) / ms->ms_cluster_size; if (!ms->ms_fat_length && vs->vs_fat32_length) max_count = FAT32_MAX; else max_count = __cluster_count > FAT12_MAX ? FAT16_MAX : FAT12_MAX; if (__cluster_count > max_count) return 0; if (fat_size) *fat_size = __fat_size; if (cluster_count) *cluster_count = __cluster_count; #if 0 if (blkid_probe_is_wholedisk(pr)) { /* OK, seems like FAT, but it's possible that we found boot * sector with crazy FAT-like stuff (magic strings, media, * etc..) before MBR. Let's make sure that there is no MBR with * usable partition. */ unsigned char *buf = (unsigned char *) ms; if (mbr_is_valid_magic(buf)) { struct dos_partition *p0 = mbr_get_partition(buf, 0); if (dos_partition_get_size(p0) != 0 && (p0->boot_ind == 0 || p0->boot_ind == 0x80)) return 0; } } #endif return 1; /* valid */ }
static struct wipe_desc * do_wipe(struct wipe_desc *wp, const char *devname, int flags) { int mode = O_RDWR, reread = 0, need_force = 0; blkid_probe pr; struct wipe_desc *w, *wp0; int zap = (flags & WP_FL_ALL) ? 1 : wp->zap; char *backup = NULL; if (!(flags & WP_FL_FORCE)) mode |= O_EXCL; pr = new_probe(devname, mode); if (!pr) return NULL; if (zap && (flags & WP_FL_BACKUP)) { const char *home = getenv ("HOME"); char *tmp = xstrdup(devname); if (!home) errx(EXIT_FAILURE, _("failed to create a signature backup, $HOME undefined")); xasprintf (&backup, "%s/wipefs-%s-", home, basename(tmp)); free(tmp); } wp0 = clone_offset(wp); while (blkid_do_probe(pr) == 0) { wp = get_desc_for_probe(wp, pr); if (!wp) break; /* Check if offset is in provided list */ w = wp0; while(w && w->offset != wp->offset) w = w->next; if (wp0 && !w) continue; /* Mark done if found in provided list */ if (w) w->on_disk = wp->on_disk; if (!wp->on_disk) continue; if (!(flags & WP_FL_FORCE) && wp->is_parttable && !blkid_probe_is_wholedisk(pr)) { warnx(_("%s: ignoring nested \"%s\" partition table " "on non-whole disk device"), devname, wp->type); need_force = 1; continue; } if (zap) { if (backup) do_backup(wp, backup); do_wipe_real(pr, devname, wp, flags); if (wp->is_parttable) reread = 1; } } for (w = wp0; w != NULL; w = w->next) { if (!w->on_disk && !(flags & WP_FL_QUIET)) warnx(_("%s: offset 0x%jx not found"), devname, (uintmax_t)w->offset); } if (need_force) warnx(_("Use the --force option to force erase.")); fsync(blkid_probe_get_fd(pr)); #ifdef BLKRRPART if (reread && (mode & O_EXCL)) rereadpt(blkid_probe_get_fd(pr), devname); #endif close(blkid_probe_get_fd(pr)); blkid_free_probe(pr); free_wipe(wp0); free(backup); return wp; }