1af28f636SEnrico Perla - Sun Microsystems /* 2af28f636SEnrico Perla - Sun Microsystems * CDDL HEADER START 3af28f636SEnrico Perla - Sun Microsystems * 4af28f636SEnrico Perla - Sun Microsystems * The contents of this file are subject to the terms of the 5af28f636SEnrico Perla - Sun Microsystems * Common Development and Distribution License (the "License"). 6af28f636SEnrico Perla - Sun Microsystems * You may not use this file except in compliance with the License. 7af28f636SEnrico Perla - Sun Microsystems * 8af28f636SEnrico Perla - Sun Microsystems * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9af28f636SEnrico Perla - Sun Microsystems * or http://www.opensolaris.org/os/licensing. 10af28f636SEnrico Perla - Sun Microsystems * See the License for the specific language governing permissions 11af28f636SEnrico Perla - Sun Microsystems * and limitations under the License. 12af28f636SEnrico Perla - Sun Microsystems * 13af28f636SEnrico Perla - Sun Microsystems * When distributing Covered Code, include this CDDL HEADER in each 14af28f636SEnrico Perla - Sun Microsystems * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15af28f636SEnrico Perla - Sun Microsystems * If applicable, add the following below this CDDL HEADER, with the 16af28f636SEnrico Perla - Sun Microsystems * fields enclosed by brackets "[]" replaced with your own identifying 17af28f636SEnrico Perla - Sun Microsystems * information: Portions Copyright [yyyy] [name of copyright owner] 18af28f636SEnrico Perla - Sun Microsystems * 19af28f636SEnrico Perla - Sun Microsystems * CDDL HEADER END 20af28f636SEnrico Perla - Sun Microsystems */ 21af28f636SEnrico Perla - Sun Microsystems /* 22af28f636SEnrico Perla - Sun Microsystems * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 23af28f636SEnrico Perla - Sun Microsystems */ 24af28f636SEnrico Perla - Sun Microsystems 25af28f636SEnrico Perla - Sun Microsystems #include <stdio.h> 26af28f636SEnrico Perla - Sun Microsystems #include <stdint.h> 27af28f636SEnrico Perla - Sun Microsystems #include <stdlib.h> 28af28f636SEnrico Perla - Sun Microsystems #include <string.h> 29af28f636SEnrico Perla - Sun Microsystems #include <libintl.h> 30af28f636SEnrico Perla - Sun Microsystems #include <unistd.h> 31af28f636SEnrico Perla - Sun Microsystems #include <fcntl.h> 32af28f636SEnrico Perla - Sun Microsystems #include <sys/types.h> 33af28f636SEnrico Perla - Sun Microsystems #include <sys/stat.h> 34af28f636SEnrico Perla - Sun Microsystems 35af28f636SEnrico Perla - Sun Microsystems #include "bblk_einfo.h" 36af28f636SEnrico Perla - Sun Microsystems #include "boot_utils.h" 37af28f636SEnrico Perla - Sun Microsystems 38af28f636SEnrico Perla - Sun Microsystems bblk_hash_t bblk_no_hash = {BBLK_NO_HASH, 0, "(no hash)", NULL}; 39af28f636SEnrico Perla - Sun Microsystems bblk_hash_t bblk_md5_hash = {BBLK_HASH_MD5, 0x10, "MD5", md5_calc}; 40af28f636SEnrico Perla - Sun Microsystems 41af28f636SEnrico Perla - Sun Microsystems bblk_hash_t *bblk_hash_list[BBLK_HASH_TOT] = { 42af28f636SEnrico Perla - Sun Microsystems &bblk_no_hash, 43af28f636SEnrico Perla - Sun Microsystems &bblk_md5_hash 44af28f636SEnrico Perla - Sun Microsystems }; 45af28f636SEnrico Perla - Sun Microsystems 46af28f636SEnrico Perla - Sun Microsystems /* 47af28f636SEnrico Perla - Sun Microsystems * einfo_compare_dotted_version() 48af28f636SEnrico Perla - Sun Microsystems * Compares two strings with an arbitrary long number of dot-separated numbers. 49af28f636SEnrico Perla - Sun Microsystems * Returns: 0 - if the version numbers are equal 50af28f636SEnrico Perla - Sun Microsystems * 1 - if str1 version number is more recent than str2 51af28f636SEnrico Perla - Sun Microsystems * 2 - if str2 version number is more recent than str1 52af28f636SEnrico Perla - Sun Microsystems * -1 - if an error occurred 53af28f636SEnrico Perla - Sun Microsystems * 54af28f636SEnrico Perla - Sun Microsystems * Comparison is done field by field, by retrieving an unsigned integer value, 55af28f636SEnrico Perla - Sun Microsystems * (missing fields are assumed as 0, but explict zeroes take precedence) so: 56af28f636SEnrico Perla - Sun Microsystems * 4.1.2.11 > 4.1.2.2 > 4.1.2.0 > 4.1.2 57af28f636SEnrico Perla - Sun Microsystems * 58af28f636SEnrico Perla - Sun Microsystems * where ">" means "more recent than". 59af28f636SEnrico Perla - Sun Microsystems */ 60af28f636SEnrico Perla - Sun Microsystems static int 61af28f636SEnrico Perla - Sun Microsystems einfo_compare_dotted_version(const char *str1, const char *str2) 62af28f636SEnrico Perla - Sun Microsystems { 63af28f636SEnrico Perla - Sun Microsystems int retval = 0; 64af28f636SEnrico Perla - Sun Microsystems char *verstr1, *verstr2, *freeptr1, *freeptr2; 65af28f636SEnrico Perla - Sun Microsystems char *parsep1, *parsep2; 66af28f636SEnrico Perla - Sun Microsystems unsigned int val_str1, val_str2; 67af28f636SEnrico Perla - Sun Microsystems 68af28f636SEnrico Perla - Sun Microsystems freeptr1 = verstr1 = strdup(str1); 69af28f636SEnrico Perla - Sun Microsystems freeptr2 = verstr2 = strdup(str2); 70af28f636SEnrico Perla - Sun Microsystems if (verstr1 == NULL || verstr2 == NULL) { 71af28f636SEnrico Perla - Sun Microsystems retval = -1; 72af28f636SEnrico Perla - Sun Microsystems goto out; 73af28f636SEnrico Perla - Sun Microsystems } 74af28f636SEnrico Perla - Sun Microsystems 75af28f636SEnrico Perla - Sun Microsystems while (verstr1 != NULL && verstr2 != NULL) { 76af28f636SEnrico Perla - Sun Microsystems parsep1 = strsep(&verstr1, "."); 77af28f636SEnrico Perla - Sun Microsystems parsep2 = strsep(&verstr2, "."); 78af28f636SEnrico Perla - Sun Microsystems 79af28f636SEnrico Perla - Sun Microsystems val_str1 = atoi(parsep1); 80af28f636SEnrico Perla - Sun Microsystems val_str2 = atoi(parsep2); 81af28f636SEnrico Perla - Sun Microsystems 82af28f636SEnrico Perla - Sun Microsystems if (val_str1 > val_str2) { 83af28f636SEnrico Perla - Sun Microsystems retval = 1; 84af28f636SEnrico Perla - Sun Microsystems goto out; 85af28f636SEnrico Perla - Sun Microsystems } 86af28f636SEnrico Perla - Sun Microsystems 87af28f636SEnrico Perla - Sun Microsystems if (val_str2 > val_str1) { 88af28f636SEnrico Perla - Sun Microsystems retval = 2; 89af28f636SEnrico Perla - Sun Microsystems goto out; 90af28f636SEnrico Perla - Sun Microsystems } 91af28f636SEnrico Perla - Sun Microsystems } 92af28f636SEnrico Perla - Sun Microsystems 93af28f636SEnrico Perla - Sun Microsystems /* Common portion of the version string is equal. */ 94af28f636SEnrico Perla - Sun Microsystems if (verstr1 == NULL && verstr2 != NULL) 95af28f636SEnrico Perla - Sun Microsystems retval = 2; 96af28f636SEnrico Perla - Sun Microsystems if (verstr2 == NULL && verstr1 != NULL) 97af28f636SEnrico Perla - Sun Microsystems retval = 1; 98af28f636SEnrico Perla - Sun Microsystems 99af28f636SEnrico Perla - Sun Microsystems out: 100af28f636SEnrico Perla - Sun Microsystems free(freeptr1); 101af28f636SEnrico Perla - Sun Microsystems free(freeptr2); 102af28f636SEnrico Perla - Sun Microsystems return (retval); 103af28f636SEnrico Perla - Sun Microsystems } 104af28f636SEnrico Perla - Sun Microsystems 105af28f636SEnrico Perla - Sun Microsystems /* 106af28f636SEnrico Perla - Sun Microsystems * einfo_compare_timestamps() 107af28f636SEnrico Perla - Sun Microsystems * Currently, timestamp is in %Y%m%dT%H%M%SZ format in UTC, which means that 108af28f636SEnrico Perla - Sun Microsystems * we can simply do a lexicographic comparison to know which one is the most 109af28f636SEnrico Perla - Sun Microsystems * recent. 110af28f636SEnrico Perla - Sun Microsystems * 111af28f636SEnrico Perla - Sun Microsystems * Returns: 0 - if timestamps coincide 112af28f636SEnrico Perla - Sun Microsystems * 1 - if the timestamp in str1 is more recent 113af28f636SEnrico Perla - Sun Microsystems * 2 - if the timestamp in str2 is more recent 114af28f636SEnrico Perla - Sun Microsystems */ 115af28f636SEnrico Perla - Sun Microsystems static int 116af28f636SEnrico Perla - Sun Microsystems einfo_compare_timestamps(const char *str1, const char *str2) 117af28f636SEnrico Perla - Sun Microsystems { 118af28f636SEnrico Perla - Sun Microsystems int retval; 119af28f636SEnrico Perla - Sun Microsystems 120af28f636SEnrico Perla - Sun Microsystems retval = strcmp(str1, str2); 121af28f636SEnrico Perla - Sun Microsystems if (retval > 0) 122af28f636SEnrico Perla - Sun Microsystems retval = 1; 123af28f636SEnrico Perla - Sun Microsystems if (retval < 0) 124af28f636SEnrico Perla - Sun Microsystems retval = 2; 125af28f636SEnrico Perla - Sun Microsystems 126af28f636SEnrico Perla - Sun Microsystems return (retval); 127af28f636SEnrico Perla - Sun Microsystems } 128af28f636SEnrico Perla - Sun Microsystems 129af28f636SEnrico Perla - Sun Microsystems /* 130af28f636SEnrico Perla - Sun Microsystems * einfo_compare_version() 131af28f636SEnrico Perla - Sun Microsystems * Given two extended versions, compare the two and returns which one is more 132af28f636SEnrico Perla - Sun Microsystems * "recent". Comparison is based on dotted version number fields and a 133af28f636SEnrico Perla - Sun Microsystems * timestamp. 134af28f636SEnrico Perla - Sun Microsystems * 135af28f636SEnrico Perla - Sun Microsystems * Returns: -1 - on error 136af28f636SEnrico Perla - Sun Microsystems * 0 - if the two versions coincide 137af28f636SEnrico Perla - Sun Microsystems * 1 - if the version in str1 is more recent 138af28f636SEnrico Perla - Sun Microsystems * 2 - if the version in str2 is more recent 139*9533a635SToomas Soome * 140*9533a635SToomas Soome * The version string generally uses following form: 141*9533a635SToomas Soome * self_release,build_release:timestamp 142*9533a635SToomas Soome * The release numbers are compared as dotted versions. 143*9533a635SToomas Soome * 144*9533a635SToomas Soome * While comparing, if the self releases are identical but the build 145*9533a635SToomas Soome * release is missing, this version string is considered older. 146*9533a635SToomas Soome * 147*9533a635SToomas Soome * If the release strings are identical, and one of the timestamps is missing, 148*9533a635SToomas Soome * we return an error. Otherwise, return the result from comparing the 149*9533a635SToomas Soome * timestamps. 150af28f636SEnrico Perla - Sun Microsystems */ 151af28f636SEnrico Perla - Sun Microsystems static int 152af28f636SEnrico Perla - Sun Microsystems einfo_compare_version(const char *str1, const char *str2) 153af28f636SEnrico Perla - Sun Microsystems { 154af28f636SEnrico Perla - Sun Microsystems int retval = 0; 155af28f636SEnrico Perla - Sun Microsystems char *verstr1, *verstr2, *freeptr1, *freeptr2; 156af28f636SEnrico Perla - Sun Microsystems char *parsep1, *parsep2; 157*9533a635SToomas Soome char *timep1, *timep2; 158af28f636SEnrico Perla - Sun Microsystems 159af28f636SEnrico Perla - Sun Microsystems freeptr1 = verstr1 = strdup(str1); 160af28f636SEnrico Perla - Sun Microsystems freeptr2 = verstr2 = strdup(str2); 161af28f636SEnrico Perla - Sun Microsystems if (verstr1 == NULL || verstr2 == NULL) { 162af28f636SEnrico Perla - Sun Microsystems retval = -1; 163af28f636SEnrico Perla - Sun Microsystems goto out; 164af28f636SEnrico Perla - Sun Microsystems } 165af28f636SEnrico Perla - Sun Microsystems 166*9533a635SToomas Soome /* Extract the time part from the version string. */ 167*9533a635SToomas Soome timep1 = verstr1; 168*9533a635SToomas Soome timep2 = verstr2; 169*9533a635SToomas Soome parsep1 = strsep(&timep1, ":"); 170*9533a635SToomas Soome parsep2 = strsep(&timep2, ":"); 171af28f636SEnrico Perla - Sun Microsystems 172af28f636SEnrico Perla - Sun Microsystems while (parsep1 != NULL && parsep2 != NULL) { 173*9533a635SToomas Soome parsep1 = strsep(&verstr1, ",-"); 174*9533a635SToomas Soome parsep2 = strsep(&verstr2, ",-"); 175af28f636SEnrico Perla - Sun Microsystems 176*9533a635SToomas Soome /* If both are NULL, compare timestamps */ 177*9533a635SToomas Soome if (parsep1 == NULL && parsep2 == NULL) 178*9533a635SToomas Soome break; 179*9533a635SToomas Soome 180*9533a635SToomas Soome if (parsep1 == NULL) { 181*9533a635SToomas Soome retval = 2; 182*9533a635SToomas Soome goto out; 183*9533a635SToomas Soome } 184*9533a635SToomas Soome if (parsep2 == NULL) { 185*9533a635SToomas Soome retval = 1; 186af28f636SEnrico Perla - Sun Microsystems goto out; 187af28f636SEnrico Perla - Sun Microsystems } 188af28f636SEnrico Perla - Sun Microsystems 189af28f636SEnrico Perla - Sun Microsystems retval = einfo_compare_dotted_version(parsep1, parsep2); 190af28f636SEnrico Perla - Sun Microsystems if (retval == 0) 191af28f636SEnrico Perla - Sun Microsystems continue; 192af28f636SEnrico Perla - Sun Microsystems else 193af28f636SEnrico Perla - Sun Microsystems goto out; 194af28f636SEnrico Perla - Sun Microsystems } 195*9533a635SToomas Soome 196*9533a635SToomas Soome /* The dotted versions are identical, check timestamps. */ 197*9533a635SToomas Soome if (timep1 == NULL || timep2 == NULL) { 198*9533a635SToomas Soome retval = -1; 199*9533a635SToomas Soome goto out; 200*9533a635SToomas Soome } 201*9533a635SToomas Soome retval = einfo_compare_timestamps(timep1, timep2); 202af28f636SEnrico Perla - Sun Microsystems out: 203af28f636SEnrico Perla - Sun Microsystems free(freeptr1); 204af28f636SEnrico Perla - Sun Microsystems free(freeptr2); 205af28f636SEnrico Perla - Sun Microsystems return (retval); 206af28f636SEnrico Perla - Sun Microsystems } 207af28f636SEnrico Perla - Sun Microsystems 208af28f636SEnrico Perla - Sun Microsystems /* 209af28f636SEnrico Perla - Sun Microsystems * print_einfo() 210af28f636SEnrico Perla - Sun Microsystems * 211af28f636SEnrico Perla - Sun Microsystems * Print the extended information contained into the pointed structure. 212af28f636SEnrico Perla - Sun Microsystems * 'bufsize' specifies the real size of the structure, since str_off and 213af28f636SEnrico Perla - Sun Microsystems * hash_off need to point somewhere past the header. 214af28f636SEnrico Perla - Sun Microsystems */ 215af28f636SEnrico Perla - Sun Microsystems void 216af28f636SEnrico Perla - Sun Microsystems print_einfo(uint8_t flags, bblk_einfo_t *einfo, unsigned long bufsize) 217af28f636SEnrico Perla - Sun Microsystems { 218af28f636SEnrico Perla - Sun Microsystems int i = 0; 219af28f636SEnrico Perla - Sun Microsystems char *version; 220af28f636SEnrico Perla - Sun Microsystems boolean_t has_hash = B_FALSE; 221110570ceSToomas Soome unsigned char *hash = NULL; 222af28f636SEnrico Perla - Sun Microsystems 223af28f636SEnrico Perla - Sun Microsystems if (einfo->str_off + einfo->str_size > bufsize) { 224af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("String offset %d is beyond the " 225af28f636SEnrico Perla - Sun Microsystems "buffer size\n"), einfo->str_off); 226af28f636SEnrico Perla - Sun Microsystems return; 227af28f636SEnrico Perla - Sun Microsystems } 228af28f636SEnrico Perla - Sun Microsystems 229af28f636SEnrico Perla - Sun Microsystems version = (char *)einfo + einfo->str_off; 230af28f636SEnrico Perla - Sun Microsystems if (einfo->hash_type != BBLK_NO_HASH && 231af28f636SEnrico Perla - Sun Microsystems einfo->hash_type < BBLK_HASH_TOT) { 232af28f636SEnrico Perla - Sun Microsystems if (einfo->hash_off + einfo->hash_size > bufsize) { 233af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, gettext("Warning: hashing " 234af28f636SEnrico Perla - Sun Microsystems "present but hash offset %d is beyond the buffer " 235af28f636SEnrico Perla - Sun Microsystems "size\n"), einfo->hash_off); 236af28f636SEnrico Perla - Sun Microsystems has_hash = B_FALSE; 237af28f636SEnrico Perla - Sun Microsystems } else { 238af28f636SEnrico Perla - Sun Microsystems hash = (unsigned char *)einfo + einfo->hash_off; 239af28f636SEnrico Perla - Sun Microsystems has_hash = B_TRUE; 240af28f636SEnrico Perla - Sun Microsystems } 241af28f636SEnrico Perla - Sun Microsystems } 242af28f636SEnrico Perla - Sun Microsystems 243af28f636SEnrico Perla - Sun Microsystems if (flags & EINFO_PRINT_HEADER) { 244af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "Boot Block Extended Info Header:\n"); 245af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\tmagic: "); 246af28f636SEnrico Perla - Sun Microsystems for (i = 0; i < EINFO_MAGIC_SIZE; i++) 247af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "%c", einfo->magic[i]); 248af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\n"); 249af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\tversion: %d\n", einfo->version); 250af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\tflags: %x\n", einfo->flags); 251af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\textended version string offset: %d\n", 252af28f636SEnrico Perla - Sun Microsystems einfo->str_off); 253af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\textended version string size: %d\n", 254af28f636SEnrico Perla - Sun Microsystems einfo->str_size); 255af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\thashing type: %d (%s)\n", 256af28f636SEnrico Perla - Sun Microsystems einfo->hash_type, has_hash ? 257af28f636SEnrico Perla - Sun Microsystems bblk_hash_list[einfo->hash_type]->name : "nil"); 258af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\thash offset: %d\n", einfo->hash_off); 259af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\thash size: %d\n", einfo->hash_size); 260af28f636SEnrico Perla - Sun Microsystems } 261af28f636SEnrico Perla - Sun Microsystems 262af28f636SEnrico Perla - Sun Microsystems if (flags & EINFO_EASY_PARSE) { 263af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "%s\n", version); 264af28f636SEnrico Perla - Sun Microsystems } else { 265af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "Extended version string: %s\n", 266af28f636SEnrico Perla - Sun Microsystems version); 267af28f636SEnrico Perla - Sun Microsystems if (has_hash) { 268af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "%s hash: ", 269af28f636SEnrico Perla - Sun Microsystems bblk_hash_list[einfo->hash_type]->name); 270af28f636SEnrico Perla - Sun Microsystems } else { 271af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "No hashing available\n"); 272af28f636SEnrico Perla - Sun Microsystems } 273af28f636SEnrico Perla - Sun Microsystems } 274af28f636SEnrico Perla - Sun Microsystems 275af28f636SEnrico Perla - Sun Microsystems if (has_hash) { 276af28f636SEnrico Perla - Sun Microsystems for (i = 0; i < einfo->hash_size; i++) { 277af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "%02x", hash[i]); 278af28f636SEnrico Perla - Sun Microsystems } 279af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stdout, "\n"); 280af28f636SEnrico Perla - Sun Microsystems } 281af28f636SEnrico Perla - Sun Microsystems } 282af28f636SEnrico Perla - Sun Microsystems 283af28f636SEnrico Perla - Sun Microsystems static int 284af28f636SEnrico Perla - Sun Microsystems compute_hash(bblk_hs_t *hs, unsigned char *dest, bblk_hash_t *hash) 285af28f636SEnrico Perla - Sun Microsystems { 286af28f636SEnrico Perla - Sun Microsystems if (hs == NULL || dest == NULL || hash == NULL) 287af28f636SEnrico Perla - Sun Microsystems return (-1); 288af28f636SEnrico Perla - Sun Microsystems 289af28f636SEnrico Perla - Sun Microsystems hash->compute_hash(dest, hs->src_buf, hs->src_size); 290af28f636SEnrico Perla - Sun Microsystems return (0); 291af28f636SEnrico Perla - Sun Microsystems } 292af28f636SEnrico Perla - Sun Microsystems 293af28f636SEnrico Perla - Sun Microsystems int 294af28f636SEnrico Perla - Sun Microsystems prepare_and_write_einfo(unsigned char *dest, char *infostr, bblk_hs_t *hs, 295af28f636SEnrico Perla - Sun Microsystems uint32_t maxsize, uint32_t *used_space) 296af28f636SEnrico Perla - Sun Microsystems { 297af28f636SEnrico Perla - Sun Microsystems uint16_t hash_size; 298af28f636SEnrico Perla - Sun Microsystems uint32_t hash_off; 299af28f636SEnrico Perla - Sun Microsystems unsigned char *data; 300af28f636SEnrico Perla - Sun Microsystems bblk_einfo_t *einfo = (bblk_einfo_t *)dest; 301af28f636SEnrico Perla - Sun Microsystems bblk_hash_t *hashinfo = bblk_hash_list[BBLK_DEFAULT_HASH]; 302af28f636SEnrico Perla - Sun Microsystems 303af28f636SEnrico Perla - Sun Microsystems /* 304af28f636SEnrico Perla - Sun Microsystems * 'dest' might be both containing the buffer we want to hash and 305af28f636SEnrico Perla - Sun Microsystems * containing our einfo structure: delay any update of it after the 306af28f636SEnrico Perla - Sun Microsystems * hashing has been calculated. 307af28f636SEnrico Perla - Sun Microsystems */ 308af28f636SEnrico Perla - Sun Microsystems hash_size = hashinfo->size; 309af28f636SEnrico Perla - Sun Microsystems hash_off = sizeof (bblk_einfo_t); 310af28f636SEnrico Perla - Sun Microsystems 311af28f636SEnrico Perla - Sun Microsystems if (hash_off + hash_size > maxsize) { 312af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to add extended info, " 313af28f636SEnrico Perla - Sun Microsystems "not enough space\n")); 314af28f636SEnrico Perla - Sun Microsystems return (-1); 315af28f636SEnrico Perla - Sun Microsystems } 316af28f636SEnrico Perla - Sun Microsystems 317af28f636SEnrico Perla - Sun Microsystems data = dest + hash_off; 318af28f636SEnrico Perla - Sun Microsystems if (compute_hash(hs, data, hashinfo) < 0) { 319af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("%s hash operation failed\n"), 320af28f636SEnrico Perla - Sun Microsystems hashinfo->name); 321af28f636SEnrico Perla - Sun Microsystems einfo->hash_type = bblk_no_hash.type; 322af28f636SEnrico Perla - Sun Microsystems einfo->hash_size = bblk_no_hash.size; 323af28f636SEnrico Perla - Sun Microsystems } else { 324af28f636SEnrico Perla - Sun Microsystems einfo->hash_type = hashinfo->type; 325af28f636SEnrico Perla - Sun Microsystems einfo->hash_size = hashinfo->size; 326af28f636SEnrico Perla - Sun Microsystems } 327af28f636SEnrico Perla - Sun Microsystems 328af28f636SEnrico Perla - Sun Microsystems (void) memcpy(einfo->magic, EINFO_MAGIC, EINFO_MAGIC_SIZE); 329af28f636SEnrico Perla - Sun Microsystems einfo->version = BBLK_EINFO_VERSION; 330af28f636SEnrico Perla - Sun Microsystems einfo->flags = 0; 331af28f636SEnrico Perla - Sun Microsystems einfo->hash_off = hash_off; 332af28f636SEnrico Perla - Sun Microsystems einfo->hash_size = hash_size; 333af28f636SEnrico Perla - Sun Microsystems einfo->str_off = einfo->hash_off + einfo->hash_size + 1; 334af28f636SEnrico Perla - Sun Microsystems 335af28f636SEnrico Perla - Sun Microsystems if (infostr == NULL) { 336af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to add extended info, " 337af28f636SEnrico Perla - Sun Microsystems "string is empty\n")); 338af28f636SEnrico Perla - Sun Microsystems return (-1); 339af28f636SEnrico Perla - Sun Microsystems } 340af28f636SEnrico Perla - Sun Microsystems einfo->str_size = strlen(infostr); 341af28f636SEnrico Perla - Sun Microsystems 342af28f636SEnrico Perla - Sun Microsystems if (einfo->str_off + einfo->str_size > maxsize) { 343af28f636SEnrico Perla - Sun Microsystems (void) fprintf(stderr, gettext("Unable to add extended info, " 344af28f636SEnrico Perla - Sun Microsystems "not enough space\n")); 345af28f636SEnrico Perla - Sun Microsystems return (-1); 346af28f636SEnrico Perla - Sun Microsystems } 347af28f636SEnrico Perla - Sun Microsystems 348af28f636SEnrico Perla - Sun Microsystems data = dest + einfo->str_off; 349af28f636SEnrico Perla - Sun Microsystems (void) memcpy(data, infostr, einfo->str_size); 350af28f636SEnrico Perla - Sun Microsystems *used_space = einfo->str_off + einfo->str_size; 351af28f636SEnrico Perla - Sun Microsystems 352af28f636SEnrico Perla - Sun Microsystems return (0); 353af28f636SEnrico Perla - Sun Microsystems } 354af28f636SEnrico Perla - Sun Microsystems 355af28f636SEnrico Perla - Sun Microsystems /* 356af28f636SEnrico Perla - Sun Microsystems * einfo_should_update() 357af28f636SEnrico Perla - Sun Microsystems * Given information on the boot block currently on disk (disk_einfo) and 358af28f636SEnrico Perla - Sun Microsystems * information on the supplied boot block (hs for hashing, verstr as the 359af28f636SEnrico Perla - Sun Microsystems * associated version string) decide if an update of the on-disk boot block 360af28f636SEnrico Perla - Sun Microsystems * is necessary or not. 361af28f636SEnrico Perla - Sun Microsystems */ 362af28f636SEnrico Perla - Sun Microsystems boolean_t 363af28f636SEnrico Perla - Sun Microsystems einfo_should_update(bblk_einfo_t *disk_einfo, bblk_hs_t *hs, char *verstr) 364af28f636SEnrico Perla - Sun Microsystems { 365af28f636SEnrico Perla - Sun Microsystems bblk_hash_t *hashing; 366af28f636SEnrico Perla - Sun Microsystems unsigned char *disk_hash; 367af28f636SEnrico Perla - Sun Microsystems unsigned char *local_hash; 368af28f636SEnrico Perla - Sun Microsystems char *disk_version; 369af28f636SEnrico Perla - Sun Microsystems int retval; 370af28f636SEnrico Perla - Sun Microsystems 371af28f636SEnrico Perla - Sun Microsystems if (disk_einfo == NULL) 372af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 373af28f636SEnrico Perla - Sun Microsystems 374af28f636SEnrico Perla - Sun Microsystems if (memcmp(disk_einfo->magic, EINFO_MAGIC, EINFO_MAGIC_SIZE) != 0) 375af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 376af28f636SEnrico Perla - Sun Microsystems 377af28f636SEnrico Perla - Sun Microsystems if (disk_einfo->version < BBLK_EINFO_VERSION) 378af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 379af28f636SEnrico Perla - Sun Microsystems 380af28f636SEnrico Perla - Sun Microsystems disk_version = einfo_get_string(disk_einfo); 381af28f636SEnrico Perla - Sun Microsystems retval = einfo_compare_version(verstr, disk_version); 382af28f636SEnrico Perla - Sun Microsystems /* 383af28f636SEnrico Perla - Sun Microsystems * If something goes wrong or if the on-disk version is more recent 384af28f636SEnrico Perla - Sun Microsystems * do not update the bootblock. 385af28f636SEnrico Perla - Sun Microsystems */ 386af28f636SEnrico Perla - Sun Microsystems if (retval == -1 || retval == 2) 387af28f636SEnrico Perla - Sun Microsystems return (B_FALSE); 388af28f636SEnrico Perla - Sun Microsystems 389af28f636SEnrico Perla - Sun Microsystems /* 390af28f636SEnrico Perla - Sun Microsystems * If we got here it means that the two version strings are either 391af28f636SEnrico Perla - Sun Microsystems * equal or the new bootblk binary is more recent. In order to save 392af28f636SEnrico Perla - Sun Microsystems * some needless writes let's use the hash to determine if an update 393af28f636SEnrico Perla - Sun Microsystems * is really necessary. 394af28f636SEnrico Perla - Sun Microsystems */ 395af28f636SEnrico Perla - Sun Microsystems if (disk_einfo->hash_type == bblk_no_hash.type) 396af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 397af28f636SEnrico Perla - Sun Microsystems 398af28f636SEnrico Perla - Sun Microsystems if (disk_einfo->hash_type >= BBLK_HASH_TOT) 399af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 400af28f636SEnrico Perla - Sun Microsystems 401af28f636SEnrico Perla - Sun Microsystems hashing = bblk_hash_list[disk_einfo->hash_type]; 402af28f636SEnrico Perla - Sun Microsystems 403af28f636SEnrico Perla - Sun Microsystems local_hash = malloc(hashing->size); 404af28f636SEnrico Perla - Sun Microsystems if (local_hash == NULL) 405af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 406af28f636SEnrico Perla - Sun Microsystems 407af28f636SEnrico Perla - Sun Microsystems /* 408af28f636SEnrico Perla - Sun Microsystems * Failure in computing the hash may mean something wrong 409af28f636SEnrico Perla - Sun Microsystems * with the boot block file. Better be conservative here. 410af28f636SEnrico Perla - Sun Microsystems */ 411af28f636SEnrico Perla - Sun Microsystems if (compute_hash(hs, local_hash, hashing) < 0) { 412af28f636SEnrico Perla - Sun Microsystems free(local_hash); 413af28f636SEnrico Perla - Sun Microsystems return (B_FALSE); 414af28f636SEnrico Perla - Sun Microsystems } 415af28f636SEnrico Perla - Sun Microsystems 416af28f636SEnrico Perla - Sun Microsystems disk_hash = (unsigned char *)einfo_get_hash(disk_einfo); 417af28f636SEnrico Perla - Sun Microsystems 418af28f636SEnrico Perla - Sun Microsystems if (memcmp(local_hash, disk_hash, disk_einfo->hash_size) == 0) { 419af28f636SEnrico Perla - Sun Microsystems free(local_hash); 420af28f636SEnrico Perla - Sun Microsystems return (B_FALSE); 421af28f636SEnrico Perla - Sun Microsystems } 422af28f636SEnrico Perla - Sun Microsystems 423af28f636SEnrico Perla - Sun Microsystems free(local_hash); 424af28f636SEnrico Perla - Sun Microsystems return (B_TRUE); 425af28f636SEnrico Perla - Sun Microsystems } 426af28f636SEnrico Perla - Sun Microsystems 427af28f636SEnrico Perla - Sun Microsystems char * 428af28f636SEnrico Perla - Sun Microsystems einfo_get_string(bblk_einfo_t *einfo) 429af28f636SEnrico Perla - Sun Microsystems { 430af28f636SEnrico Perla - Sun Microsystems if (einfo == NULL) 431af28f636SEnrico Perla - Sun Microsystems return (NULL); 432af28f636SEnrico Perla - Sun Microsystems 433af28f636SEnrico Perla - Sun Microsystems return ((char *)einfo + einfo->str_off); 434af28f636SEnrico Perla - Sun Microsystems } 435af28f636SEnrico Perla - Sun Microsystems 436af28f636SEnrico Perla - Sun Microsystems char * 437af28f636SEnrico Perla - Sun Microsystems einfo_get_hash(bblk_einfo_t *einfo) 438af28f636SEnrico Perla - Sun Microsystems { 439af28f636SEnrico Perla - Sun Microsystems if (einfo == NULL) 440af28f636SEnrico Perla - Sun Microsystems return (NULL); 441af28f636SEnrico Perla - Sun Microsystems 442af28f636SEnrico Perla - Sun Microsystems return ((char *)einfo + einfo->hash_off); 443af28f636SEnrico Perla - Sun Microsystems } 444