1245700Snwhitehorn/*- 2245700Snwhitehorn * Copyright (c) 2013 Nathan Whitehorn 3245700Snwhitehorn * All rights reserved. 4245700Snwhitehorn * 5245700Snwhitehorn * Redistribution and use in source and binary forms, with or without 6245700Snwhitehorn * modification, are permitted provided that the following conditions 7245700Snwhitehorn * are met: 8245700Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9245700Snwhitehorn * notice, this list of conditions and the following disclaimer. 10245700Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11245700Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12245700Snwhitehorn * documentation and/or other materials provided with the distribution. 13245700Snwhitehorn * 14245700Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15245700Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16245700Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17245700Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18245700Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19245700Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20245700Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21245700Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22245700Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23245700Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24245700Snwhitehorn * SUCH DAMAGE. 25245700Snwhitehorn * 26245700Snwhitehorn * $FreeBSD$ 27245700Snwhitehorn */ 28245700Snwhitehorn 29245700Snwhitehorn#include <sys/param.h> 30245700Snwhitehorn#include <errno.h> 31245700Snwhitehorn#include <libutil.h> 32245700Snwhitehorn#include <inttypes.h> 33245700Snwhitehorn 34245700Snwhitehorn#include <libgeom.h> 35245700Snwhitehorn#include <dialog.h> 36245700Snwhitehorn#include <dlg_keys.h> 37245700Snwhitehorn 38245700Snwhitehorn#include "partedit.h" 39245700Snwhitehorn 40245700Snwhitehornstatic struct gprovider * 41245700Snwhitehornprovider_for_name(struct gmesh *mesh, const char *name) 42245700Snwhitehorn{ 43245700Snwhitehorn struct gclass *classp; 44245700Snwhitehorn struct gprovider *pp = NULL; 45245700Snwhitehorn struct ggeom *gp; 46245700Snwhitehorn 47245700Snwhitehorn LIST_FOREACH(classp, &mesh->lg_class, lg_class) { 48245700Snwhitehorn LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { 49245700Snwhitehorn if (LIST_EMPTY(&gp->lg_provider)) 50245700Snwhitehorn continue; 51245700Snwhitehorn 52245700Snwhitehorn LIST_FOREACH(pp, &gp->lg_provider, lg_provider) 53245700Snwhitehorn if (strcmp(pp->lg_name, name) == 0) 54245700Snwhitehorn break; 55245700Snwhitehorn 56245700Snwhitehorn if (pp != NULL) break; 57245700Snwhitehorn } 58245700Snwhitehorn 59245700Snwhitehorn if (pp != NULL) break; 60245700Snwhitehorn } 61245700Snwhitehorn 62245700Snwhitehorn return (pp); 63245700Snwhitehorn} 64245700Snwhitehorn 65245700Snwhitehornstatic int 66245700Snwhitehornpart_config(char *disk, const char *scheme, char *config) 67245700Snwhitehorn{ 68245700Snwhitehorn char *partition, *ap, *size = NULL, *type = NULL, *mount = NULL; 69245700Snwhitehorn struct gclass *classp; 70245700Snwhitehorn struct gmesh mesh; 71245700Snwhitehorn struct ggeom *gpart = NULL; 72245700Snwhitehorn int error; 73245700Snwhitehorn 74245700Snwhitehorn if (scheme == NULL) 75245700Snwhitehorn scheme = default_scheme(); 76245700Snwhitehorn 77245700Snwhitehorn error = geom_gettree(&mesh); 78245796Snwhitehorn if (provider_for_name(&mesh, disk) == NULL) { 79245796Snwhitehorn fprintf(stderr, "GEOM provider %s not found\n", disk); 80245796Snwhitehorn geom_deletetree(&mesh); 81245796Snwhitehorn return (-1); 82245796Snwhitehorn } 83245700Snwhitehorn 84245700Snwhitehorn /* Remove any existing partitioning and create new scheme */ 85245700Snwhitehorn LIST_FOREACH(classp, &mesh.lg_class, lg_class) 86245700Snwhitehorn if (strcmp(classp->lg_name, "PART") == 0) 87245700Snwhitehorn break; 88245700Snwhitehorn if (classp != NULL) { 89245700Snwhitehorn LIST_FOREACH(gpart, &classp->lg_geom, lg_geom) 90245700Snwhitehorn if (strcmp(gpart->lg_name, disk) == 0) 91245700Snwhitehorn break; 92245700Snwhitehorn } 93245700Snwhitehorn if (gpart != NULL) 94245700Snwhitehorn gpart_destroy(gpart); 95245700Snwhitehorn gpart_partition(disk, scheme); 96245700Snwhitehorn 97245700Snwhitehorn if (strcmp(scheme, "PC98") == 0 || strcmp(scheme, "MBR") == 0) { 98245700Snwhitehorn struct gmesh submesh; 99245700Snwhitehorn geom_gettree(&submesh); 100245700Snwhitehorn gpart_create(provider_for_name(&submesh, disk), 101245700Snwhitehorn "freebsd", NULL, NULL, &disk, 0); 102245700Snwhitehorn geom_deletetree(&submesh); 103245700Snwhitehorn } else { 104245700Snwhitehorn disk= strdup(disk); 105245700Snwhitehorn } 106245700Snwhitehorn 107245700Snwhitehorn geom_deletetree(&mesh); 108245700Snwhitehorn error = geom_gettree(&mesh); 109245700Snwhitehorn 110245700Snwhitehorn /* Create partitions */ 111245701Snwhitehorn if (config == NULL) { 112273831Snwhitehorn wizard_makeparts(&mesh, disk, "ufs", 0); 113245701Snwhitehorn goto finished; 114245701Snwhitehorn } 115245701Snwhitehorn 116245700Snwhitehorn while ((partition = strsep(&config, ",")) != NULL) { 117245700Snwhitehorn while ((ap = strsep(&partition, " \t\n")) != NULL) { 118245700Snwhitehorn if (*ap == '\0') 119245700Snwhitehorn continue; 120245700Snwhitehorn if (size == NULL) 121245700Snwhitehorn size = ap; 122245700Snwhitehorn else if (type == NULL) 123245700Snwhitehorn type = ap; 124245700Snwhitehorn else if (mount == NULL) 125245700Snwhitehorn mount = ap; 126245700Snwhitehorn } 127245700Snwhitehorn if (size == NULL) 128245700Snwhitehorn continue; 129245700Snwhitehorn if (strcmp(size, "auto") == 0) 130245700Snwhitehorn size = NULL; 131245700Snwhitehorn gpart_create(provider_for_name(&mesh, disk), type, size, mount, 132245700Snwhitehorn NULL, 0); 133245700Snwhitehorn geom_deletetree(&mesh); 134245700Snwhitehorn error = geom_gettree(&mesh); 135245700Snwhitehorn size = type = mount = NULL; 136245700Snwhitehorn } 137245700Snwhitehorn 138245701Snwhitehornfinished: 139245700Snwhitehorn geom_deletetree(&mesh); 140245700Snwhitehorn free(disk); 141245700Snwhitehorn 142245700Snwhitehorn return (0); 143245700Snwhitehorn} 144245700Snwhitehorn 145245700Snwhitehornstatic 146245700Snwhitehornint parse_disk_config(char *input) 147245700Snwhitehorn{ 148245700Snwhitehorn char *ap; 149245700Snwhitehorn char *disk = NULL, *scheme = NULL, *partconfig = NULL; 150245700Snwhitehorn 151245700Snwhitehorn while (input != NULL && *input != 0) { 152245700Snwhitehorn if (isspace(*input)) { 153245700Snwhitehorn input++; 154245700Snwhitehorn continue; 155245700Snwhitehorn } 156245700Snwhitehorn 157245700Snwhitehorn switch(*input) { 158245700Snwhitehorn case '{': 159245700Snwhitehorn input++; 160245700Snwhitehorn partconfig = strchr(input, '}'); 161245700Snwhitehorn if (partconfig == NULL) { 162245700Snwhitehorn fprintf(stderr, "Malformed partition setup " 163245700Snwhitehorn "string: %s\n", input); 164245700Snwhitehorn return (1); 165245700Snwhitehorn } 166245700Snwhitehorn *partconfig = '\0'; 167245700Snwhitehorn ap = partconfig+1; 168245700Snwhitehorn partconfig = input; 169245700Snwhitehorn input = ap; 170245700Snwhitehorn break; 171245700Snwhitehorn default: 172245700Snwhitehorn if (disk == NULL) 173245700Snwhitehorn disk = strsep(&input, " \t\n"); 174245700Snwhitehorn else if (scheme == NULL) 175245700Snwhitehorn scheme = strsep(&input, " \t\n"); 176245700Snwhitehorn else { 177245700Snwhitehorn fprintf(stderr, "Unknown directive: %s\n", 178245700Snwhitehorn strsep(&input, " \t\n")); 179245700Snwhitehorn return (1); 180245700Snwhitehorn } 181245700Snwhitehorn } 182245700Snwhitehorn } while (input != NULL && *input != 0); 183245700Snwhitehorn 184245700Snwhitehorn if (disk != NULL) 185245796Snwhitehorn return (part_config(disk, scheme, partconfig)); 186245700Snwhitehorn 187245700Snwhitehorn return (0); 188245700Snwhitehorn} 189245700Snwhitehorn 190245700Snwhitehornint 191245700Snwhitehornscripted_editor(int argc, const char **argv) 192245700Snwhitehorn{ 193245700Snwhitehorn char *token; 194245796Snwhitehorn int i, error = 0, len = 0; 195245700Snwhitehorn 196245700Snwhitehorn for (i = 1; i < argc; i++) 197245700Snwhitehorn len += strlen(argv[i]) + 1; 198245700Snwhitehorn char inputbuf[len], *input = inputbuf; 199245700Snwhitehorn strcpy(input, argv[1]); 200245700Snwhitehorn for (i = 2; i < argc; i++) { 201245700Snwhitehorn strcat(input, " "); 202245700Snwhitehorn strcat(input, argv[i]); 203245700Snwhitehorn } 204245700Snwhitehorn 205245796Snwhitehorn while ((token = strsep(&input, ";")) != NULL) { 206245796Snwhitehorn error = parse_disk_config(token); 207245796Snwhitehorn if (error != 0) 208245796Snwhitehorn return (error); 209245796Snwhitehorn } 210245700Snwhitehorn 211245700Snwhitehorn return (0); 212245700Snwhitehorn} 213245700Snwhitehorn 214