| 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 | } |