Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | /* |
2 | * ========== Copyright Header Begin ========================================== | |
3 | * | |
4 | * Hypervisor Software File: finddropin.c | |
5 | * | |
6 | * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
7 | * | |
8 | * - Do no alter or remove copyright notices | |
9 | * | |
10 | * - Redistribution and use of this software in source and binary forms, with | |
11 | * or without modification, are permitted provided that the following | |
12 | * conditions are met: | |
13 | * | |
14 | * - Redistribution of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * | |
17 | * - Redistribution in binary form must reproduce the above copyright notice, | |
18 | * this list of conditions and the following disclaimer in the | |
19 | * documentation and/or other materials provided with the distribution. | |
20 | * | |
21 | * Neither the name of Sun Microsystems, Inc. or the names of contributors | |
22 | * may be used to endorse or promote products derived from this software | |
23 | * without specific prior written permission. | |
24 | * | |
25 | * This software is provided "AS IS," without a warranty of any kind. | |
26 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
27 | * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
28 | * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
29 | * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
30 | * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
31 | * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
32 | * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
33 | * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
34 | * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
35 | * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
36 | * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
37 | * | |
38 | * You acknowledge that this software is not designed, licensed or | |
39 | * intended for use in the design, construction, operation or maintenance of | |
40 | * any nuclear facility. | |
41 | * | |
42 | * ========== Copyright Header End ============================================ | |
43 | */ | |
44 | /* | |
45 | * id: @(#)finddropin.c 1.1 03/04/01 | |
46 | * purpose: | |
47 | * copyright: Copyright 2000, 2003 Sun Microsystems, Inc. All Rights Reserved | |
48 | * copyright: Use is subject to license terms. | |
49 | */ | |
50 | ||
51 | #include <sys/dilib.h> | |
52 | #include <strings.h> | |
53 | #include <stdlib.h> | |
54 | #include <unistd.h> | |
55 | #include <stdio.h> | |
56 | ||
57 | caddr_t | |
58 | extract_string(dropin_data_t *data) | |
59 | { | |
60 | int32_t len = data->size+1; | |
61 | static char str[0x80]; | |
62 | ||
63 | if (len > 0x80) { | |
64 | return (NULL); | |
65 | } | |
66 | memset(str, 0, len); | |
67 | strncpy(str, (caddr_t)data->data, data->size); | |
68 | return (strdup(str)); | |
69 | } | |
70 | ||
71 | static uchar_t * | |
72 | do_lempel_ziv(uchar_t *src, int32_t len, int32_t dlen, int32_t verbose) | |
73 | { | |
74 | uchar_t *data, *dbuf; | |
75 | int32_t nlen = 0; | |
76 | ||
77 | dbuf = (uchar_t *)malloc(dlen); | |
78 | if (dbuf == NULL) { | |
79 | di_bail("Malloc Failed"); | |
80 | return (0); | |
81 | } | |
82 | nlen = di_decomp(src, len, dbuf); | |
83 | if (verbose > 0) { | |
84 | printf("Decompress: %d/%d bytes, [%d], ratio %2.2f:1\n", | |
85 | len, dlen, nlen, (((float)dlen)/((float)len))); | |
86 | } | |
87 | data = (uchar_t *)malloc(dlen); | |
88 | if (data == NULL) { | |
89 | di_bail("Malloc Failed"); | |
90 | return (0); | |
91 | } | |
92 | memcpy(data, dbuf, dlen); | |
93 | free(dbuf); | |
94 | return (data); | |
95 | } | |
96 | ||
97 | int32_t | |
98 | di_getdata(obmd_t *src, int32_t verbose, dropin_data_t *rdata) | |
99 | { | |
100 | uint32_t *dptr = (uint32_t *)((caddr_t)src + OBMD_HDR); | |
101 | uchar_t *data = (uchar_t *)dptr; | |
102 | int32_t dlen = src->size; | |
103 | compresshdr *chdr = (compresshdr *) dptr; | |
104 | ||
105 | if ((chdr->magic == COMP_MAGIC) && (src->size == chdr->comp_size)) { | |
106 | int32_t clen = chdr->comp_size; | |
107 | int32_t type = chdr->type; | |
108 | dlen = chdr->decomp_size; | |
109 | ||
110 | switch (type) { | |
111 | case COMP_MAGIC: | |
112 | if (verbose > 0) { | |
113 | printf("[COMP: %x,%x]\n", clen, dlen); | |
114 | } | |
115 | data = do_lempel_ziv(data+sizeof (compresshdr), | |
116 | clen, dlen, (verbose-1)); | |
117 | dptr = (uint32_t *)data; | |
118 | break; | |
119 | ||
120 | default: | |
121 | printf("Unknown compression type: %d\n", type); | |
122 | break; | |
123 | } | |
124 | } | |
125 | ||
126 | rdata->data = data; | |
127 | rdata->size = dlen; | |
128 | if (dptr[0] == OBME_MAGIC) { | |
129 | rdata->data += sizeof (obme_t); | |
130 | rdata->size -= sizeof (obme_t); | |
131 | } | |
132 | return (0); | |
133 | } | |
134 | ||
135 | int32_t | |
136 | di_isdropin(obmd_t *src) | |
137 | { | |
138 | return (strncmp((caddr_t)src, "OBMD", 4) == 0); | |
139 | } | |
140 | ||
141 | int32_t | |
142 | di_islevel2(obmd_t *src) | |
143 | { | |
144 | uchar_t *bdata = ((uchar_t *)src)+OBMD_HDR; | |
145 | int32_t *data = (int32_t *)bdata; | |
146 | return (di_isdropin(src) && (data[0] == OBME_MAGIC)); | |
147 | } | |
148 | ||
149 | static obmd_t * | |
150 | di_iterate(caddr_t name, obmd_t *src, int32_t size, int32_t verbose, | |
151 | int32_t instance) | |
152 | { | |
153 | int32_t dlen, bytes = 0; | |
154 | int32_t num_found = 1; | |
155 | obmd_t *found = NULL; | |
156 | uchar_t *next; | |
157 | ||
158 | ||
159 | if (verbose > 0) { | |
160 | printf("di_iterate: '%s'\n", name); | |
161 | } | |
162 | /* | |
163 | * Iterate through the chunk looking for dropins | |
164 | */ | |
165 | while ((found == NULL) && (bytes < size) && (num_found <= instance)) { | |
166 | next = (uchar_t *)src; | |
167 | while (*next == 1) { | |
168 | next++; | |
169 | bytes++; | |
170 | } | |
171 | src = (obmd_t *)next; | |
172 | if (!di_isdropin(src)) break; | |
173 | if (verbose > 0) { | |
174 | printf("..di: '%s' [%d]\n", src->name, src->size); | |
175 | printf("instance = %i\n", instance); | |
176 | } | |
177 | if (strcmp(name, src->name) == 0) { | |
178 | if (instance == num_found) | |
179 | found = src; | |
180 | else { | |
181 | num_found++; | |
182 | dlen = src->size + OBMD_HDR; | |
183 | next += dlen; | |
184 | bytes += dlen; | |
185 | src = (obmd_t *)next; | |
186 | } | |
187 | } else { | |
188 | dlen = src->size + OBMD_HDR; | |
189 | next += dlen; | |
190 | bytes += dlen; | |
191 | src = (obmd_t *)next; | |
192 | } | |
193 | } | |
194 | return (found); | |
195 | } | |
196 | ||
197 | obmd_t * | |
198 | di_finddropin(caddr_t name, obmd_t *src, int32_t filesize, | |
199 | int32_t verbose, int32_t instance) | |
200 | { | |
201 | caddr_t dir; | |
202 | obmd_t *data = NULL; | |
203 | caddr_t container; | |
204 | caddr_t slash; | |
205 | uchar_t *shift; | |
206 | uchar_t *next; | |
207 | dropin_data_t dropin_data; | |
208 | int32_t i = 0; | |
209 | int32_t size = filesize; | |
210 | ||
211 | ||
212 | ||
213 | shift = (uchar_t *)src; | |
214 | while (*shift == 1) { | |
215 | if (verbose > 0) printf("x"); | |
216 | shift++; | |
217 | } | |
218 | src = (obmd_t *)shift; | |
219 | if (*name == '/') { | |
220 | name++; | |
221 | di_getdata(src, (verbose-1), &dropin_data); | |
222 | src = (obmd_t *)dropin_data.data; | |
223 | size = dropin_data.size; | |
224 | } | |
225 | if (*name == 0) { | |
226 | if (verbose > 0) { | |
227 | printf("<empty filename>\n"); | |
228 | } | |
229 | return (NULL); | |
230 | } | |
231 | if (!di_isdropin(src)) { | |
232 | if (verbose > 0) { | |
233 | printf("<Not a dropin>\n"); | |
234 | } | |
235 | return (NULL); | |
236 | } | |
237 | if (size <= 0) { | |
238 | if (verbose > 0) { | |
239 | printf("<no more bytes>\n"); | |
240 | } | |
241 | return (NULL); | |
242 | } | |
243 | container = strdup(name); | |
244 | dir = slash = strchr(container, '/'); | |
245 | if (slash) { | |
246 | *slash = 0; | |
247 | dir = slash+1; | |
248 | } | |
249 | if (verbose > 0) { | |
250 | printf("Path: %s [%x]\n", name, size); | |
251 | } | |
252 | ||
253 | next = (uchar_t *)src; | |
254 | while ((++i <= instance) && (src != NULL)) { | |
255 | data = di_iterate(container, src, filesize, (verbose-1), 1); | |
256 | next += (src->size + OBMD_HDR); | |
257 | src = (obmd_t *)next; | |
258 | } | |
259 | ||
260 | if (data != NULL) { | |
261 | obmd_t *new; | |
262 | int32_t new_size; | |
263 | /* | |
264 | * we found it | |
265 | */ | |
266 | if (verbose > 0) { | |
267 | printf("Dropin: '%s', [%d]\n", data->name, data->size); | |
268 | } | |
269 | if (dir) { | |
270 | di_getdata(data, (verbose-1), &dropin_data); | |
271 | new = (obmd_t *)dropin_data.data; | |
272 | new_size = dropin_data.size; | |
273 | if (verbose > 0) { | |
274 | printf("Descending into: %s [%d]\n", | |
275 | data->name, data->size); | |
276 | } | |
277 | data = di_finddropin(dir, new, new_size, | |
278 | (verbose-1), 1); | |
279 | } | |
280 | } | |
281 | return (data); | |
282 | } |