partedit.c revision 225066
1218799Snwhitehorn/*- 2218799Snwhitehorn * Copyright (c) 2011 Nathan Whitehorn 3218799Snwhitehorn * All rights reserved. 4218799Snwhitehorn * 5218799Snwhitehorn * Redistribution and use in source and binary forms, with or without 6218799Snwhitehorn * modification, are permitted provided that the following conditions 7218799Snwhitehorn * are met: 8218799Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9218799Snwhitehorn * notice, this list of conditions and the following disclaimer. 10218799Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11218799Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12218799Snwhitehorn * documentation and/or other materials provided with the distribution. 13218799Snwhitehorn * 14218799Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15218799Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16218799Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17218799Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18218799Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19218799Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20218799Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21218799Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22218799Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23218799Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24218799Snwhitehorn * SUCH DAMAGE. 25218799Snwhitehorn * 26218799Snwhitehorn * $FreeBSD: head/usr.sbin/bsdinstall/partedit/partedit.c 225066 2011-08-21 18:50:30Z nwhitehorn $ 27218799Snwhitehorn */ 28218799Snwhitehorn 29218799Snwhitehorn#include <sys/param.h> 30218799Snwhitehorn#include <libgen.h> 31218799Snwhitehorn#include <libutil.h> 32218799Snwhitehorn#include <inttypes.h> 33218799Snwhitehorn#include <errno.h> 34218799Snwhitehorn 35218799Snwhitehorn#include <fstab.h> 36218799Snwhitehorn#include <libgeom.h> 37218799Snwhitehorn#include <dialog.h> 38218799Snwhitehorn#include <dlg_keys.h> 39218799Snwhitehorn 40218799Snwhitehorn#include "diskeditor.h" 41218799Snwhitehorn#include "partedit.h" 42218799Snwhitehorn 43218799Snwhitehornstruct pmetadata_head part_metadata; 44218799Snwhitehorn 45218799Snwhitehornstatic int apply_changes(struct gmesh *mesh); 46218799Snwhitehornstatic struct partedit_item *read_geom_mesh(struct gmesh *mesh, int *nitems); 47218799Snwhitehornstatic void add_geom_children(struct ggeom *gp, int recurse, 48218799Snwhitehorn struct partedit_item **items, int *nitems); 49218799Snwhitehornstatic void init_fstab_metadata(void); 50218799Snwhitehornstatic void get_mount_points(struct partedit_item *items, int nitems); 51218799Snwhitehornstatic int validate_setup(void); 52218799Snwhitehorn 53225066Snwhitehornstatic void 54225066Snwhitehornsigint_handler(int sig) 55225066Snwhitehorn{ 56225066Snwhitehorn struct gmesh mesh; 57225066Snwhitehorn 58225066Snwhitehorn /* Revert all changes and exit dialog-mode cleanly on SIGINT */ 59225066Snwhitehorn geom_gettree(&mesh); 60225066Snwhitehorn gpart_revert_all(&mesh); 61225066Snwhitehorn geom_deletetree(&mesh); 62225066Snwhitehorn 63225066Snwhitehorn end_dialog(); 64225066Snwhitehorn 65225066Snwhitehorn exit(1); 66225066Snwhitehorn} 67225066Snwhitehorn 68218799Snwhitehornint 69225066Snwhitehornmain(int argc, const char **argv) 70225066Snwhitehorn{ 71218799Snwhitehorn struct partition_metadata *md; 72218799Snwhitehorn const char *prompt; 73218799Snwhitehorn struct partedit_item *items; 74218799Snwhitehorn struct gmesh mesh; 75218799Snwhitehorn int i, op, nitems, nscroll; 76218799Snwhitehorn int error; 77218799Snwhitehorn 78218799Snwhitehorn TAILQ_INIT(&part_metadata); 79218799Snwhitehorn 80218799Snwhitehorn init_fstab_metadata(); 81218799Snwhitehorn 82218799Snwhitehorn init_dialog(stdin, stdout); 83218799Snwhitehorn if (strcmp(basename(argv[0]), "sade") != 0) 84218799Snwhitehorn dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); 85218799Snwhitehorn dialog_vars.item_help = TRUE; 86218799Snwhitehorn nscroll = i = 0; 87218799Snwhitehorn 88225066Snwhitehorn /* Revert changes on SIGINT */ 89225066Snwhitehorn signal(SIGINT, sigint_handler); 90225066Snwhitehorn 91218799Snwhitehorn if (strcmp(basename(argv[0]), "autopart") == 0) { /* Guided */ 92218799Snwhitehorn prompt = "Please review the disk setup. When complete, press " 93225066Snwhitehorn "the Finish button."; 94218799Snwhitehorn part_wizard(); 95218799Snwhitehorn } else { 96218799Snwhitehorn prompt = "Create partitions for FreeBSD. No changes will be " 97225066Snwhitehorn "made until you select Finish."; 98218799Snwhitehorn } 99218799Snwhitehorn 100218799Snwhitehorn /* Show the part editor either immediately, or to confirm wizard */ 101218799Snwhitehorn while (1) { 102218799Snwhitehorn error = geom_gettree(&mesh); 103218799Snwhitehorn items = read_geom_mesh(&mesh, &nitems); 104218799Snwhitehorn get_mount_points(items, nitems); 105218799Snwhitehorn dlg_clear(); 106218799Snwhitehorn dlg_put_backtitle(); 107218799Snwhitehorn 108218799Snwhitehorn if (i >= nitems) 109218799Snwhitehorn i = nitems - 1; 110218799Snwhitehorn op = diskeditor_show("Partition Editor", prompt, 111218799Snwhitehorn items, nitems, &i, &nscroll); 112218799Snwhitehorn 113218799Snwhitehorn switch (op) { 114218799Snwhitehorn case 0: /* Create */ 115218799Snwhitehorn gpart_create((struct gprovider *)(items[i].cookie), 116218799Snwhitehorn NULL, NULL, NULL, NULL, 1); 117218799Snwhitehorn break; 118218799Snwhitehorn case 1: /* Delete */ 119218799Snwhitehorn gpart_delete((struct gprovider *)(items[i].cookie)); 120218799Snwhitehorn break; 121218799Snwhitehorn case 2: /* Modify */ 122218799Snwhitehorn gpart_edit((struct gprovider *)(items[i].cookie)); 123218799Snwhitehorn break; 124218799Snwhitehorn case 3: /* Revert */ 125218799Snwhitehorn gpart_revert_all(&mesh); 126218799Snwhitehorn while ((md = TAILQ_FIRST(&part_metadata)) != NULL) { 127218799Snwhitehorn if (md->fstab != NULL) { 128218799Snwhitehorn free(md->fstab->fs_spec); 129218799Snwhitehorn free(md->fstab->fs_file); 130218799Snwhitehorn free(md->fstab->fs_vfstype); 131218799Snwhitehorn free(md->fstab->fs_mntops); 132218799Snwhitehorn free(md->fstab->fs_type); 133218799Snwhitehorn free(md->fstab); 134218799Snwhitehorn } 135218799Snwhitehorn if (md->newfs != NULL) 136218799Snwhitehorn free(md->newfs); 137218799Snwhitehorn free(md->name); 138218799Snwhitehorn 139218799Snwhitehorn TAILQ_REMOVE(&part_metadata, md, metadata); 140218799Snwhitehorn free(md); 141218799Snwhitehorn } 142218799Snwhitehorn init_fstab_metadata(); 143218799Snwhitehorn break; 144218799Snwhitehorn case 4: /* Auto */ 145218799Snwhitehorn part_wizard(); 146218799Snwhitehorn break; 147218799Snwhitehorn } 148218799Snwhitehorn 149218799Snwhitehorn error = 0; 150219391Snwhitehorn if (op == 5) { /* Finished */ 151225066Snwhitehorn dialog_vars.ok_label = __DECONST(char *, "Commit"); 152225066Snwhitehorn dialog_vars.extra_label = 153225066Snwhitehorn __DECONST(char *, "Revert & Exit"); 154218799Snwhitehorn dialog_vars.extra_button = TRUE; 155225066Snwhitehorn dialog_vars.cancel_label = __DECONST(char *, "Back"); 156218799Snwhitehorn op = dialog_yesno("Confirmation", "Your changes will " 157218799Snwhitehorn "now be written to disk. If you have chosen to " 158218799Snwhitehorn "overwrite existing data, it will be PERMANENTLY " 159225066Snwhitehorn "ERASED. Are you sure you want to commit your " 160225066Snwhitehorn "changes?", 0, 0); 161225066Snwhitehorn dialog_vars.ok_label = NULL; 162218799Snwhitehorn dialog_vars.extra_button = FALSE; 163225066Snwhitehorn dialog_vars.cancel_label = NULL; 164218799Snwhitehorn 165219391Snwhitehorn if (op == 0 && validate_setup()) { /* Save */ 166218799Snwhitehorn error = apply_changes(&mesh); 167218799Snwhitehorn break; 168225066Snwhitehorn } else if (op == 3) { /* Quit */ 169218799Snwhitehorn gpart_revert_all(&mesh); 170218799Snwhitehorn error = -1; 171218799Snwhitehorn break; 172218799Snwhitehorn } 173218799Snwhitehorn } 174218799Snwhitehorn 175218799Snwhitehorn geom_deletetree(&mesh); 176218799Snwhitehorn free(items); 177218799Snwhitehorn } 178218799Snwhitehorn 179218799Snwhitehorn 180218799Snwhitehorn geom_deletetree(&mesh); 181218799Snwhitehorn free(items); 182218799Snwhitehorn end_dialog(); 183218799Snwhitehorn 184218799Snwhitehorn return (error); 185218799Snwhitehorn} 186218799Snwhitehorn 187218799Snwhitehornstruct partition_metadata * 188218799Snwhitehornget_part_metadata(const char *name, int create) 189218799Snwhitehorn{ 190218799Snwhitehorn struct partition_metadata *md; 191218799Snwhitehorn 192218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) 193218799Snwhitehorn if (md->name != NULL && strcmp(md->name, name) == 0) 194218799Snwhitehorn break; 195218799Snwhitehorn 196218799Snwhitehorn if (md == NULL && create) { 197218799Snwhitehorn md = calloc(1, sizeof(*md)); 198218799Snwhitehorn md->name = strdup(name); 199218799Snwhitehorn TAILQ_INSERT_TAIL(&part_metadata, md, metadata); 200218799Snwhitehorn } 201218799Snwhitehorn 202218799Snwhitehorn return (md); 203218799Snwhitehorn} 204218799Snwhitehorn 205218799Snwhitehornvoid 206225066Snwhitehorndelete_part_metadata(const char *name) 207225066Snwhitehorn{ 208218799Snwhitehorn struct partition_metadata *md; 209218799Snwhitehorn 210218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 211218799Snwhitehorn if (md->name != NULL && strcmp(md->name, name) == 0) { 212218799Snwhitehorn if (md->fstab != NULL) { 213218799Snwhitehorn free(md->fstab->fs_spec); 214218799Snwhitehorn free(md->fstab->fs_file); 215218799Snwhitehorn free(md->fstab->fs_vfstype); 216218799Snwhitehorn free(md->fstab->fs_mntops); 217218799Snwhitehorn free(md->fstab->fs_type); 218218799Snwhitehorn free(md->fstab); 219218799Snwhitehorn } 220218799Snwhitehorn if (md->newfs != NULL) 221218799Snwhitehorn free(md->newfs); 222218799Snwhitehorn free(md->name); 223218799Snwhitehorn 224218799Snwhitehorn TAILQ_REMOVE(&part_metadata, md, metadata); 225218799Snwhitehorn free(md); 226218799Snwhitehorn break; 227218799Snwhitehorn } 228218799Snwhitehorn } 229218799Snwhitehorn} 230218799Snwhitehorn 231218799Snwhitehornstatic int 232218799Snwhitehornvalidate_setup(void) 233218799Snwhitehorn{ 234218799Snwhitehorn struct partition_metadata *md; 235218799Snwhitehorn int root_found = FALSE; 236218799Snwhitehorn 237218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 238218799Snwhitehorn if (md->fstab != NULL && strcmp(md->fstab->fs_file, "/") == 0) 239218799Snwhitehorn root_found = TRUE; 240218799Snwhitehorn 241218799Snwhitehorn /* XXX: Check for duplicate mountpoints */ 242218799Snwhitehorn } 243218799Snwhitehorn 244218799Snwhitehorn if (!root_found) { 245218799Snwhitehorn dialog_msgbox("Error", "No root partition was found. " 246218799Snwhitehorn "The root FreeBSD partition must have a mountpoint of '/'.", 247218799Snwhitehorn 0, 0, TRUE); 248218799Snwhitehorn return (FALSE); 249218799Snwhitehorn } 250218799Snwhitehorn 251218799Snwhitehorn return (TRUE); 252218799Snwhitehorn} 253218799Snwhitehorn 254218799Snwhitehornstatic int 255218799Snwhitehornapply_changes(struct gmesh *mesh) 256218799Snwhitehorn{ 257218799Snwhitehorn struct partition_metadata *md; 258218799Snwhitehorn char message[512]; 259218799Snwhitehorn int i, nitems, error; 260218799Snwhitehorn const char **items; 261218799Snwhitehorn const char *fstab_path; 262218799Snwhitehorn FILE *fstab; 263218799Snwhitehorn 264218799Snwhitehorn nitems = 1; /* Partition table changes */ 265218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 266218799Snwhitehorn if (md->newfs != NULL) 267218799Snwhitehorn nitems++; 268218799Snwhitehorn } 269218799Snwhitehorn items = calloc(nitems * 2, sizeof(const char *)); 270218799Snwhitehorn items[0] = "Writing partition tables"; 271218799Snwhitehorn items[1] = "7"; /* In progress */ 272218799Snwhitehorn i = 1; 273218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 274218799Snwhitehorn if (md->newfs != NULL) { 275218799Snwhitehorn char *item; 276218799Snwhitehorn item = malloc(255); 277218799Snwhitehorn sprintf(item, "Initializing %s", md->name); 278218799Snwhitehorn items[i*2] = item; 279218799Snwhitehorn items[i*2 + 1] = "Pending"; 280218799Snwhitehorn i++; 281218799Snwhitehorn } 282218799Snwhitehorn } 283218799Snwhitehorn 284218799Snwhitehorn i = 0; 285218799Snwhitehorn dialog_mixedgauge("Initializing", 286218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, i*100/nitems, 287218799Snwhitehorn nitems, __DECONST(char **, items)); 288218799Snwhitehorn gpart_commit(mesh); 289218799Snwhitehorn items[i*2 + 1] = "3"; 290218799Snwhitehorn i++; 291218799Snwhitehorn 292218799Snwhitehorn if (getenv("BSDINSTALL_LOG") == NULL) 293218799Snwhitehorn setenv("BSDINSTALL_LOG", "/dev/null", 1); 294218799Snwhitehorn 295218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 296218799Snwhitehorn if (md->newfs != NULL) { 297218799Snwhitehorn items[i*2 + 1] = "7"; /* In progress */ 298218799Snwhitehorn dialog_mixedgauge("Initializing", 299218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, 300218799Snwhitehorn i*100/nitems, nitems, __DECONST(char **, items)); 301218799Snwhitehorn sprintf(message, "(echo %s; %s) >>%s 2>>%s", 302218799Snwhitehorn md->newfs, md->newfs, getenv("BSDINSTALL_LOG"), 303218799Snwhitehorn getenv("BSDINSTALL_LOG")); 304218799Snwhitehorn error = system(message); 305218799Snwhitehorn items[i*2 + 1] = (error == 0) ? "3" : "1"; 306218799Snwhitehorn i++; 307218799Snwhitehorn } 308218799Snwhitehorn } 309218799Snwhitehorn dialog_mixedgauge("Initializing", 310218799Snwhitehorn "Initializing file systems. Please wait.", 0, 0, 311218799Snwhitehorn i*100/nitems, nitems, __DECONST(char **, items)); 312218799Snwhitehorn 313218799Snwhitehorn for (i = 1; i < nitems; i++) 314218799Snwhitehorn free(__DECONST(char *, items[i*2])); 315218799Snwhitehorn free(items); 316218799Snwhitehorn 317218799Snwhitehorn if (getenv("PATH_FSTAB") != NULL) 318218799Snwhitehorn fstab_path = getenv("PATH_FSTAB"); 319218799Snwhitehorn else 320218799Snwhitehorn fstab_path = "/etc/fstab"; 321218799Snwhitehorn fstab = fopen(fstab_path, "w+"); 322218799Snwhitehorn if (fstab == NULL) { 323218799Snwhitehorn sprintf(message, "Cannot open fstab file %s for writing (%s)\n", 324218799Snwhitehorn getenv("PATH_FSTAB"), strerror(errno)); 325218799Snwhitehorn dialog_msgbox("Error", message, 0, 0, TRUE); 326218799Snwhitehorn return (-1); 327218799Snwhitehorn } 328218799Snwhitehorn fprintf(fstab, "# Device\tMountpoint\tFStype\tOptions\tDump\tPass#\n"); 329218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 330218799Snwhitehorn if (md->fstab != NULL) 331223832Skevlo fprintf(fstab, "%s\t%s\t\t%s\t%s\t%d\t%d\n", 332218799Snwhitehorn md->fstab->fs_spec, md->fstab->fs_file, 333218799Snwhitehorn md->fstab->fs_vfstype, md->fstab->fs_mntops, 334218799Snwhitehorn md->fstab->fs_freq, md->fstab->fs_passno); 335218799Snwhitehorn } 336218799Snwhitehorn fclose(fstab); 337218799Snwhitehorn 338218799Snwhitehorn return (0); 339218799Snwhitehorn} 340218799Snwhitehorn 341218799Snwhitehornstatic struct partedit_item * 342225066Snwhitehornread_geom_mesh(struct gmesh *mesh, int *nitems) 343225066Snwhitehorn{ 344218799Snwhitehorn struct gclass *classp; 345218799Snwhitehorn struct ggeom *gp; 346218799Snwhitehorn struct partedit_item *items; 347218799Snwhitehorn 348218799Snwhitehorn *nitems = 0; 349218799Snwhitehorn items = NULL; 350218799Snwhitehorn 351218799Snwhitehorn /* 352218799Snwhitehorn * Build the device table. First add all disks (and CDs). 353218799Snwhitehorn */ 354218799Snwhitehorn 355218799Snwhitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) { 356218799Snwhitehorn if (strcmp(classp->lg_name, "DISK") != 0 && 357225066Snwhitehorn strcmp(classp->lg_name, "MD") != 0) 358218799Snwhitehorn continue; 359218799Snwhitehorn 360218799Snwhitehorn /* Now recurse into all children */ 361218799Snwhitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) 362218799Snwhitehorn add_geom_children(gp, 0, &items, nitems); 363218799Snwhitehorn } 364218799Snwhitehorn 365218799Snwhitehorn return (items); 366218799Snwhitehorn} 367218799Snwhitehorn 368218799Snwhitehornstatic void 369218799Snwhitehornadd_geom_children(struct ggeom *gp, int recurse, struct partedit_item **items, 370225066Snwhitehorn int *nitems) 371225066Snwhitehorn{ 372218799Snwhitehorn struct gconsumer *cp; 373218799Snwhitehorn struct gprovider *pp; 374218799Snwhitehorn struct gconfig *gc; 375218799Snwhitehorn 376218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "PART") == 0 && 377218799Snwhitehorn !LIST_EMPTY(&gp->lg_config)) { 378218799Snwhitehorn LIST_FOREACH(gc, &gp->lg_config, lg_config) { 379218799Snwhitehorn if (strcmp(gc->lg_name, "scheme") == 0) 380218799Snwhitehorn (*items)[*nitems-1].type = gc->lg_val; 381218799Snwhitehorn } 382218799Snwhitehorn } 383218799Snwhitehorn 384218799Snwhitehorn if (LIST_EMPTY(&gp->lg_provider)) 385218799Snwhitehorn return; 386218799Snwhitehorn 387218799Snwhitehorn LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 388218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "LABEL") == 0) 389218799Snwhitehorn continue; 390218799Snwhitehorn 391218799Snwhitehorn /* Skip WORM media */ 392218799Snwhitehorn if (strncmp(pp->lg_name, "cd", 2) == 0) 393218799Snwhitehorn continue; 394218799Snwhitehorn 395218799Snwhitehorn *items = realloc(*items, 396218799Snwhitehorn (*nitems+1)*sizeof(struct partedit_item)); 397218799Snwhitehorn (*items)[*nitems].indentation = recurse; 398218799Snwhitehorn (*items)[*nitems].name = pp->lg_name; 399218799Snwhitehorn (*items)[*nitems].size = pp->lg_mediasize; 400218799Snwhitehorn (*items)[*nitems].mountpoint = NULL; 401218799Snwhitehorn (*items)[*nitems].type = ""; 402218799Snwhitehorn (*items)[*nitems].cookie = pp; 403218799Snwhitehorn 404218799Snwhitehorn LIST_FOREACH(gc, &pp->lg_config, lg_config) { 405218799Snwhitehorn if (strcmp(gc->lg_name, "type") == 0) 406218799Snwhitehorn (*items)[*nitems].type = gc->lg_val; 407218799Snwhitehorn } 408218799Snwhitehorn 409218799Snwhitehorn /* Skip swap-backed MD devices */ 410218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "MD") == 0 && 411218799Snwhitehorn strcmp((*items)[*nitems].type, "swap") == 0) 412218799Snwhitehorn continue; 413218799Snwhitehorn 414218799Snwhitehorn (*nitems)++; 415218799Snwhitehorn 416218799Snwhitehorn LIST_FOREACH(cp, &pp->lg_consumers, lg_consumers) 417218799Snwhitehorn add_geom_children(cp->lg_geom, recurse+1, items, 418218799Snwhitehorn nitems); 419218799Snwhitehorn 420218799Snwhitehorn /* Only use first provider for acd */ 421218799Snwhitehorn if (strcmp(gp->lg_class->lg_name, "ACD") == 0) 422218799Snwhitehorn break; 423218799Snwhitehorn } 424218799Snwhitehorn} 425218799Snwhitehorn 426218799Snwhitehornstatic void 427218799Snwhitehorninit_fstab_metadata(void) 428218799Snwhitehorn{ 429218799Snwhitehorn struct fstab *fstab; 430218799Snwhitehorn struct partition_metadata *md; 431218799Snwhitehorn 432218799Snwhitehorn setfsent(); 433218799Snwhitehorn while ((fstab = getfsent()) != NULL) { 434218799Snwhitehorn md = calloc(1, sizeof(struct partition_metadata)); 435218799Snwhitehorn 436218799Snwhitehorn md->name = NULL; 437218799Snwhitehorn if (strncmp(fstab->fs_spec, "/dev/", 5) == 0) 438218799Snwhitehorn md->name = strdup(&fstab->fs_spec[5]); 439218799Snwhitehorn 440218799Snwhitehorn md->fstab = malloc(sizeof(struct fstab)); 441218799Snwhitehorn md->fstab->fs_spec = strdup(fstab->fs_spec); 442218799Snwhitehorn md->fstab->fs_file = strdup(fstab->fs_file); 443218799Snwhitehorn md->fstab->fs_vfstype = strdup(fstab->fs_vfstype); 444218799Snwhitehorn md->fstab->fs_mntops = strdup(fstab->fs_mntops); 445218799Snwhitehorn md->fstab->fs_type = strdup(fstab->fs_type); 446218799Snwhitehorn md->fstab->fs_freq = fstab->fs_freq; 447218799Snwhitehorn md->fstab->fs_passno = fstab->fs_passno; 448218799Snwhitehorn 449218799Snwhitehorn md->newfs = NULL; 450218799Snwhitehorn 451218799Snwhitehorn TAILQ_INSERT_TAIL(&part_metadata, md, metadata); 452218799Snwhitehorn } 453218799Snwhitehorn} 454218799Snwhitehorn 455218799Snwhitehornstatic void 456218799Snwhitehornget_mount_points(struct partedit_item *items, int nitems) 457218799Snwhitehorn{ 458218799Snwhitehorn struct partition_metadata *md; 459218799Snwhitehorn int i; 460218799Snwhitehorn 461218799Snwhitehorn for (i = 0; i < nitems; i++) { 462218799Snwhitehorn TAILQ_FOREACH(md, &part_metadata, metadata) { 463218799Snwhitehorn if (md->name != NULL && md->fstab != NULL && 464218799Snwhitehorn strcmp(md->name, items[i].name) == 0) { 465218799Snwhitehorn items[i].mountpoint = md->fstab->fs_file; 466218799Snwhitehorn break; 467218799Snwhitehorn } 468218799Snwhitehorn } 469218799Snwhitehorn } 470218799Snwhitehorn} 471