char *label; /* FS label */
char *uuid; /* FS uuid */
+ int on_disk;
+
struct wipe_desc *next;
};
}
static struct wipe_desc *
-get_offset_from_probe(struct wipe_desc *wp, blkid_probe pr, int zap)
+get_desc_for_probe(struct wipe_desc *wp, blkid_probe pr)
{
const char *off, *type, *usage, *mag;
size_t len;
loff_t offset = strtoll(off, NULL, 10);
const char *p;
- wp = add_offset(wp, offset, zap);
+ wp = add_offset(wp, offset, 0);
if (!wp)
return NULL;
wp->usage = xstrdup(usage);
wp->type = xstrdup(type);
+ wp->on_disk = 1;
wp->magic = xmalloc(len);
memcpy(wp->magic, mag, len);
return wp;
}
-static struct wipe_desc *
-read_offsets(struct wipe_desc *wp, const char *fname, int zap)
+static blkid_probe
+new_probe(const char *devname, int mode)
{
blkid_probe pr;
int rc;
- if (!fname)
+ if (!devname)
return NULL;
- pr = blkid_new_probe_from_filename(fname);
+ if (mode) {
+ int fd = open(devname, mode);
+ if (fd < 0)
+ goto error;
+
+ pr = blkid_new_probe();
+ if (pr && blkid_probe_set_device(pr, fd, 0, 0))
+ goto error;
+ } else
+ pr = blkid_new_probe_from_filename(devname);
+
if (!pr)
- errx(EXIT_FAILURE, _("error: %s: probing initialization failed"), fname);
+ goto error;
blkid_probe_enable_superblocks(pr, 0); /* enabled by default ;-( */
const char *type = NULL;
blkid_probe_lookup_value(pr, "PTTYPE", &type, NULL);
warnx(_("WARNING: %s: appears to contain '%s' "
- "partition table"), fname, type);
+ "partition table"), devname, type);
}
blkid_probe_enable_superblocks(pr, 1);
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_USAGE |
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);
+ return pr;
+error:
+ err(EXIT_FAILURE, _("error: %s: probing initialization failed"), devname);
+ return NULL;
+}
+
+static struct wipe_desc *
+read_offsets(struct wipe_desc *wp, const char *devname)
+{
+ blkid_probe pr = new_probe(devname, 0);
+
+ if (!pr)
+ return NULL;
+
while (blkid_do_probe(pr) == 0) {
- wp = get_offset_from_probe(wp, pr, zap);
+ wp = get_desc_for_probe(wp, pr);
if (!wp)
break;
}
return wp;
}
-static int
-do_wipe_offset(int fd, struct wipe_desc *wp, const char *fname, int noact)
+static struct wipe_desc *
+do_wipe(struct wipe_desc *wp, const char *devname, int noact, int all)
{
- char buf[BUFSIZ];
- off_t l;
- size_t i, len;
-
- if (!wp->type) {
- warnx(_("no magic string found at offset "
- "0x%jx -- ignored"), wp->offset);
- return 0;
- }
-
- l = lseek(fd, wp->offset, SEEK_SET);
- if (l == (off_t) -1)
- err(EXIT_FAILURE, _("%s: failed to seek to offset 0x%jx"),
- fname, wp->offset);
-
- len = wp->len > sizeof(buf) ? sizeof(buf) : wp->len;
-
- memset(buf, 0, len);
- if (noact == 0 && write_all(fd, buf, len))
- err(EXIT_FAILURE, _("%s: write failed"), fname);
+ blkid_probe pr = new_probe(devname, O_RDWR);
+ struct wipe_desc *w;
- printf(_("%zd bytes were erased at offset 0x%jx (%s)\nthey were: "),
- wp->len, wp->offset, wp->type);
+ if (!pr)
+ return NULL;
- for (i = 0; i < len; i++) {
- printf("%02x", wp->magic[i]);
- if (i + 1 < len)
- fputc(' ', stdout);
+ while (blkid_do_probe(pr) == 0) {
+ w = get_desc_for_probe(wp, pr);
+ if (!w)
+ break;
+ wp = w;
+ if (!wp->on_disk)
+ continue;
+ wp->zap = all ? 1 : wp->zap;
+ if (!wp->zap)
+ continue;
+
+ if (blkid_do_wipe(pr, noact))
+ warn(_("failed to erase %s magic string at offset 0x%08jx"),
+ wp->type, wp->offset);
+ else {
+ size_t i;
+
+ printf(_("%zd bytes were erased at offset 0x%08jx (%s): "),
+ wp->len, wp->offset, wp->type);
+
+ for (i = 0; i < wp->len; i++) {
+ printf("%02x", wp->magic[i]);
+ if (i + 1 < wp->len)
+ fputc(' ', stdout);
+ }
+ putchar('\n');
+ }
}
- printf("\n");
- return 0;
-}
-
-static int
-do_wipe(struct wipe_desc *wp, const char *fname, int noact)
-{
- int fd;
-
- fd = open(fname, O_WRONLY);
- if (fd < 0)
- err(EXIT_FAILURE, _("%s: open failed"), fname);
-
- while (wp) {
- if (wp->zap)
- do_wipe_offset(fd, wp, fname, noact);
- wp = wp->next;
+ for (w = wp; w != NULL; w = w->next) {
+ if (!w->on_disk)
+ warnx(_("offset 0x%jx not found"), w->offset);
}
- close(fd);
- return 0;
+ fsync(blkid_probe_get_fd(pr));
+ close(blkid_probe_get_fd(pr));
+ blkid_free_probe(pr);
+
+ return wp;
}
static void
{
struct wipe_desc *wp = NULL;
int c, all = 0, has_offset = 0, noact = 0, mode = 0;
- const char *fname;
+ const char *devname;
static const struct option longopts[] = {
{ "all", 0, 0, 'a' },
if (optind == argc)
usage(stderr);
- fname = argv[optind++];
+ devname = argv[optind++];
if (optind != argc)
errx(EXIT_FAILURE, _("only one device as argument is currently supported."));
- wp = read_offsets(wp, fname, all);
-
- if (wp) {
- if (has_offset || all)
- do_wipe(wp, fname, noact);
- else
+ if (!all && !has_offset) {
+ /*
+ * Print only
+ */
+ wp = read_offsets(wp, devname);
+ if (wp)
print_all(wp, mode);
-
- free_wipe(wp);
+ } else {
+ /*
+ * Erase
+ */
+ wp = do_wipe(wp, devname, noact, all);
}
+
+ free_wipe(wp);
return EXIT_SUCCESS;
}