Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tools/regression/geom/MdLoad/MdLoad.c
48254 views
1
/*-
2
* Copyright (c) 2003 Poul-Henning Kamp
3
* Copyright (c) 2002 Networks Associates Technology, Inc.
4
* All rights reserved.
5
*
6
* This software was developed for the FreeBSD Project by Poul-Henning Kamp
7
* and NAI Labs, the Security Research Division of Network Associates, Inc.
8
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9
* DARPA CHATS research program.
10
*
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
13
* are met:
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. The names of the authors may not be used to endorse or promote
20
* products derived from this software without specific prior written
21
* permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33
* SUCH DAMAGE.
34
*/
35
36
#include <stdio.h>
37
#include <stdlib.h>
38
#include <unistd.h>
39
#include <stdint.h>
40
#include <string.h>
41
#include <ctype.h>
42
#include <errno.h>
43
#include <paths.h>
44
#include <fcntl.h>
45
#include <err.h>
46
#include <bsdxml.h>
47
#include <sys/types.h>
48
#include <sys/stat.h>
49
#include <sys/queue.h>
50
#include <sys/sbuf.h>
51
#include <sys/mman.h>
52
53
struct sector {
54
LIST_ENTRY(sector) sectors;
55
off_t offset;
56
unsigned char *data;
57
};
58
59
struct simdisk_softc {
60
int sectorsize;
61
off_t mediasize;
62
off_t lastsector;
63
LIST_HEAD(,sector) sectors;
64
struct sbuf *sbuf;
65
struct sector *sp;
66
u_int fwsectors;
67
u_int fwheads;
68
u_int fwcylinders;
69
};
70
71
static void
72
g_simdisk_insertsector(struct simdisk_softc *sc, struct sector *dsp)
73
{
74
struct sector *dsp2, *dsp3;
75
76
if (sc->lastsector < dsp->offset)
77
sc->lastsector = dsp->offset;
78
if (LIST_EMPTY(&sc->sectors)) {
79
LIST_INSERT_HEAD(&sc->sectors, dsp, sectors);
80
return;
81
}
82
dsp3 = NULL;
83
LIST_FOREACH(dsp2, &sc->sectors, sectors) {
84
dsp3 = dsp2;
85
if (dsp2->offset > dsp->offset) {
86
LIST_INSERT_BEFORE(dsp2, dsp, sectors);
87
return;
88
}
89
}
90
LIST_INSERT_AFTER(dsp3, dsp, sectors);
91
}
92
93
static void
94
startElement(void *userData, const char *name, const char **atts __unused)
95
{
96
struct simdisk_softc *sc;
97
98
sc = userData;
99
if (!strcasecmp(name, "sector")) {
100
sc->sp = calloc(1, sizeof(*sc->sp) + sc->sectorsize);
101
sc->sp->data = (u_char *)(sc->sp + 1);
102
}
103
sbuf_clear(sc->sbuf);
104
}
105
106
static void
107
endElement(void *userData, const char *name)
108
{
109
struct simdisk_softc *sc;
110
char *p;
111
u_char *q;
112
int i, j;
113
off_t o;
114
115
sc = userData;
116
117
if (!strcasecmp(name, "comment")) {
118
sbuf_clear(sc->sbuf);
119
return;
120
}
121
sbuf_finish(sc->sbuf);
122
if (!strcasecmp(name, "sectorsize")) {
123
sc->sectorsize = strtoul(sbuf_data(sc->sbuf), &p, 0);
124
if (*p != '\0')
125
errx(1, "strtoul croaked on sectorsize");
126
} else if (!strcasecmp(name, "mediasize")) {
127
o = strtoull(sbuf_data(sc->sbuf), &p, 0);
128
if (*p != '\0')
129
errx(1, "strtoul croaked on mediasize");
130
if (o > 0)
131
sc->mediasize = o;
132
} else if (!strcasecmp(name, "fwsectors")) {
133
sc->fwsectors = strtoul(sbuf_data(sc->sbuf), &p, 0);
134
if (*p != '\0')
135
errx(1, "strtoul croaked on fwsectors");
136
} else if (!strcasecmp(name, "fwheads")) {
137
sc->fwheads = strtoul(sbuf_data(sc->sbuf), &p, 0);
138
if (*p != '\0')
139
errx(1, "strtoul croaked on fwheads");
140
} else if (!strcasecmp(name, "fwcylinders")) {
141
sc->fwcylinders = strtoul(sbuf_data(sc->sbuf), &p, 0);
142
if (*p != '\0')
143
errx(1, "strtoul croaked on fwcylinders");
144
} else if (!strcasecmp(name, "offset")) {
145
sc->sp->offset= strtoull(sbuf_data(sc->sbuf), &p, 0);
146
if (*p != '\0')
147
errx(1, "strtoul croaked on offset");
148
} else if (!strcasecmp(name, "fill")) {
149
j = strtoul(sbuf_data(sc->sbuf), NULL, 16);
150
memset(sc->sp->data, j, sc->sectorsize);
151
} else if (!strcasecmp(name, "hexdata")) {
152
q = sc->sp->data;
153
p = sbuf_data(sc->sbuf);
154
for (i = 0; i < sc->sectorsize; i++) {
155
if (!isxdigit(*p))
156
errx(1, "I croaked on hexdata %d:(%02x)", i, *p);
157
if (isdigit(*p))
158
j = (*p - '0') << 4;
159
else
160
j = (tolower(*p) - 'a' + 10) << 4;
161
p++;
162
if (!isxdigit(*p))
163
errx(1, "I croaked on hexdata %d:(%02x)", i, *p);
164
if (isdigit(*p))
165
j |= *p - '0';
166
else
167
j |= tolower(*p) - 'a' + 10;
168
p++;
169
*q++ = j;
170
}
171
} else if (!strcasecmp(name, "sector")) {
172
g_simdisk_insertsector(sc, sc->sp);
173
sc->sp = NULL;
174
} else if (!strcasecmp(name, "diskimage")) {
175
} else if (!strcasecmp(name, "FreeBSD")) {
176
} else {
177
printf("<%s>[[%s]]\n", name, sbuf_data(sc->sbuf));
178
}
179
sbuf_clear(sc->sbuf);
180
}
181
182
static void
183
characterData(void *userData, const XML_Char *s, int len)
184
{
185
const char *b, *e;
186
struct simdisk_softc *sc;
187
188
sc = userData;
189
b = s;
190
e = s + len - 1;
191
while (isspace(*b) && b < e)
192
b++;
193
while (isspace(*e) && e > b)
194
e--;
195
if (e != b || !isspace(*b))
196
sbuf_bcat(sc->sbuf, b, e - b + 1);
197
}
198
199
static struct simdisk_softc *
200
g_simdisk_xml_load(const char *file)
201
{
202
XML_Parser parser = XML_ParserCreate(NULL);
203
struct stat st;
204
char *p;
205
struct simdisk_softc *sc;
206
int fd, i;
207
208
sc = calloc(1, sizeof *sc);
209
sc->sbuf = sbuf_new_auto();
210
LIST_INIT(&sc->sectors);
211
XML_SetUserData(parser, sc);
212
XML_SetElementHandler(parser, startElement, endElement);
213
XML_SetCharacterDataHandler(parser, characterData);
214
215
fd = open(file, O_RDONLY);
216
if (fd < 0)
217
err(1, "%s", file);
218
fstat(fd, &st);
219
p = mmap(NULL, st.st_size, PROT_READ, MAP_NOCORE|MAP_PRIVATE, fd, 0);
220
i = XML_Parse(parser, p, st.st_size, 1);
221
if (i != 1)
222
errx(1, "XML_Parse complains: return %d", i);
223
munmap(p, st.st_size);
224
close(fd);
225
XML_ParserFree(parser);
226
return (sc);
227
}
228
229
int
230
main(int argc, char **argv)
231
{
232
struct simdisk_softc *sc;
233
char buf[BUFSIZ];
234
int error, fd;
235
struct sector *dsp;
236
237
if (argc != 3)
238
errx(1, "Usage: %s mddevice xmlfile", argv[0]);
239
240
sc = g_simdisk_xml_load(argv[2]);
241
if (sc->mediasize == 0)
242
sc->mediasize = sc->lastsector + sc->sectorsize * 10;
243
if (sc->sectorsize == 0)
244
sc->sectorsize = 512;
245
sprintf(buf, "mdconfig -a -t malloc -s %jd -S %d",
246
(intmax_t)sc->mediasize / sc->sectorsize, sc->sectorsize);
247
if (sc->fwsectors && sc->fwheads)
248
sprintf(buf + strlen(buf), " -x %d -y %d",
249
sc->fwsectors, sc->fwheads);
250
sprintf(buf + strlen(buf), " -u %s", argv[1]);
251
error = system(buf);
252
if (error)
253
return (error);
254
fd = open(argv[1], O_RDWR);
255
if (fd < 0 && errno == ENOENT) {
256
sprintf(buf, "%s%s", _PATH_DEV, argv[1]);
257
fd = open(buf, O_RDWR);
258
}
259
if (fd < 0)
260
err(1, "Could not open %s", argv[1]);
261
LIST_FOREACH(dsp, &sc->sectors, sectors) {
262
lseek(fd, dsp->offset, SEEK_SET);
263
error = write(fd, dsp->data, sc->sectorsize);
264
if (error != sc->sectorsize)
265
err(1, "write sectordata failed");
266
}
267
close(fd);
268
exit (0);
269
}
270
271