Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bsdinstall/partedit/scripted.c
101998 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2013 Nathan Whitehorn
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/param.h>
30
31
#include <ctype.h>
32
#include <libgeom.h>
33
#include <stdio.h>
34
#include <stdlib.h>
35
#include <string.h>
36
37
#include "partedit.h"
38
39
static struct gprovider *
40
provider_for_name(struct gmesh *mesh, const char *name)
41
{
42
struct gclass *classp;
43
struct gprovider *pp = NULL;
44
struct ggeom *gp;
45
46
LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
47
LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
48
if (LIST_EMPTY(&gp->lg_provider))
49
continue;
50
51
LIST_FOREACH(pp, &gp->lg_provider, lg_provider)
52
if (strcmp(pp->lg_name, name) == 0)
53
break;
54
55
if (pp != NULL) break;
56
}
57
58
if (pp != NULL) break;
59
}
60
61
return (pp);
62
}
63
64
static int
65
part_config(char *disk, const char *scheme, char *config)
66
{
67
char *partition, *ap, *size = NULL, *type = NULL, *mount = NULL;
68
struct gclass *classp;
69
struct gmesh mesh;
70
struct ggeom *gpart = NULL;
71
int error;
72
73
if (scheme == NULL)
74
scheme = default_scheme();
75
76
error = geom_gettree(&mesh);
77
if (error != 0)
78
return (-1);
79
if (provider_for_name(&mesh, disk) == NULL) {
80
fprintf(stderr, "GEOM provider %s not found\n", disk);
81
geom_deletetree(&mesh);
82
return (-1);
83
}
84
85
/* Remove any existing partitioning and create new scheme */
86
LIST_FOREACH(classp, &mesh.lg_class, lg_class)
87
if (strcmp(classp->lg_name, "PART") == 0)
88
break;
89
if (classp != NULL) {
90
LIST_FOREACH(gpart, &classp->lg_geom, lg_geom)
91
if (strcmp(gpart->lg_name, disk) == 0)
92
break;
93
}
94
if (gpart != NULL)
95
gpart_destroy(gpart);
96
gpart_partition(disk, scheme);
97
98
if (strcmp(scheme, "MBR") == 0) {
99
struct gmesh submesh;
100
101
if (geom_gettree(&submesh) == 0) {
102
gpart_create(provider_for_name(&submesh, disk),
103
"freebsd", NULL, NULL, &disk, 0);
104
geom_deletetree(&submesh);
105
}
106
} else {
107
disk = strdup(disk);
108
}
109
110
geom_deletetree(&mesh);
111
error = geom_gettree(&mesh);
112
if (error != 0) {
113
free(disk);
114
return (-1);
115
}
116
117
/* Create partitions */
118
if (config == NULL) {
119
wizard_makeparts(&mesh, disk, "ufs", 0);
120
goto finished;
121
}
122
123
while ((partition = strsep(&config, ",")) != NULL) {
124
while ((ap = strsep(&partition, " \t\n")) != NULL) {
125
if (*ap == '\0')
126
continue;
127
if (size == NULL)
128
size = ap;
129
else if (type == NULL)
130
type = ap;
131
else if (mount == NULL)
132
mount = ap;
133
}
134
if (size == NULL)
135
continue;
136
if (strcmp(size, "auto") == 0)
137
size = NULL;
138
gpart_create(provider_for_name(&mesh, disk), type, size, mount,
139
NULL, 0);
140
geom_deletetree(&mesh);
141
error = geom_gettree(&mesh);
142
if (error != 0) {
143
free(disk);
144
return (-1);
145
}
146
size = type = mount = NULL;
147
}
148
149
finished:
150
geom_deletetree(&mesh);
151
free(disk);
152
153
return (0);
154
}
155
156
static int
157
parse_disk_config(char *input)
158
{
159
char *ap;
160
char *disk = NULL, *scheme = NULL, *partconfig = NULL;
161
162
while (input != NULL && *input != 0) {
163
if (isspace(*input)) {
164
input++;
165
continue;
166
}
167
168
switch(*input) {
169
case '{':
170
input++;
171
partconfig = strchr(input, '}');
172
if (partconfig == NULL) {
173
fprintf(stderr, "Malformed partition setup "
174
"string: %s\n", input);
175
return (1);
176
}
177
*partconfig = '\0';
178
ap = partconfig+1;
179
partconfig = input;
180
input = ap;
181
break;
182
default:
183
if (disk == NULL)
184
disk = strsep(&input, " \t\n");
185
else if (scheme == NULL)
186
scheme = strsep(&input, " \t\n");
187
else {
188
fprintf(stderr, "Unknown directive: %s\n",
189
strsep(&input, " \t\n"));
190
return (1);
191
}
192
}
193
} while (input != NULL && *input != 0);
194
195
if (disk == NULL || strcmp(disk, "DEFAULT") == 0) {
196
struct gmesh mesh;
197
198
if (geom_gettree(&mesh) == 0) {
199
disk = boot_disk_select(&mesh);
200
geom_deletetree(&mesh);
201
}
202
}
203
204
return (part_config(disk, scheme, partconfig));
205
}
206
207
int
208
scripted_editor(int argc, const char **argv)
209
{
210
FILE *fp;
211
char *input, *token;
212
size_t len;
213
int i, error = 0;
214
215
fp = open_memstream(&input, &len);
216
fputs(argv[1], fp);
217
for (i = 2; i < argc; i++) {
218
fprintf(fp, " %s", argv[i]);
219
}
220
fclose(fp);
221
222
while ((token = strsep(&input, ";")) != NULL) {
223
error = parse_disk_config(token);
224
if (error != 0) {
225
free(input);
226
return (error);
227
}
228
}
229
free(input);
230
231
return (0);
232
}
233
234
235