/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <unistd.h>
#include <fcntl.h>
#include "bblk_einfo.h"
#include "boot_utils.h"
};
/*
* einfo_compare_dotted_version()
* Compares two strings with an arbitrary long number of dot-separated numbers.
* Returns: 0 - if the version numbers are equal
* 1 - if str1 version number is more recent than str2
* 2 - if str2 version number is more recent than str1
* -1 - if an error occurred
*
* Comparison is done field by field, by retrieving an unsigned integer value,
* (missing fields are assumed as 0, but explict zeroes take precedence) so:
* 4.1.2.11 > 4.1.2.2 > 4.1.2.0 > 4.1.2
*
* where ">" means "more recent than".
*/
static int
{
int retval = 0;
retval = -1;
goto out;
}
retval = 1;
goto out;
}
retval = 2;
goto out;
}
}
/* Common portion of the version string is equal. */
retval = 2;
retval = 1;
out:
return (retval);
}
/*
* einfo_compare_timestamps()
* Currently, timestamp is in %Y%m%dT%H%M%SZ format in UTC, which means that
* we can simply do a lexicographic comparison to know which one is the most
* recent.
*
* Returns: 0 - if timestamps coincide
* 1 - if the timestamp in str1 is more recent
* 2 - if the timestamp in str2 is more recent
*/
static int
{
int retval;
if (retval > 0)
retval = 1;
if (retval < 0)
retval = 2;
return (retval);
}
/*
* einfo_compare_version()
* Given two extended versions, compare the two and returns which one is more
* "recent". Comparison is based on dotted version number fields and a
* timestamp.
*
* Returns: -1 - on error
* 0 - if the two versions coincide
* 1 - if the version in str1 is more recent
* 2 - if the version in str2 is more recent
*/
static int
{
int retval = 0;
retval = -1;
goto out;
}
/* verstr1 or verstr2 will be NULL before parsep1 or parsep2. */
goto out;
}
if (retval == 0)
continue;
else
goto out;
}
out:
return (retval);
}
/*
* print_einfo()
*
* Print the extended information contained into the pointed structure.
* 'bufsize' specifies the real size of the structure, since str_off and
* hash_off need to point somewhere past the header.
*/
void
{
int i = 0;
char *version;
return;
}
"present but hash offset %d is beyond the buffer "
} else {
}
}
if (flags & EINFO_PRINT_HEADER) {
for (i = 0; i < EINFO_MAGIC_SIZE; i++)
}
if (flags & EINFO_EASY_PARSE) {
} else {
version);
if (has_hash) {
} else {
}
}
if (has_hash) {
}
}
}
static int
{
return (-1);
return (0);
}
int
{
unsigned char *data;
/*
* 'dest' might be both containing the buffer we want to hash and
* containing our einfo structure: delay any update of it after the
* hashing has been calculated.
*/
hash_off = sizeof (bblk_einfo_t);
"not enough space\n"));
return (-1);
}
} else {
}
"string is empty\n"));
return (-1);
}
"not enough space\n"));
return (-1);
}
return (0);
}
/*
* einfo_should_update()
* Given information on the boot block currently on disk (disk_einfo) and
* information on the supplied boot block (hs for hashing, verstr as the
* associated version string) decide if an update of the on-disk boot block
* is necessary or not.
*/
{
unsigned char *disk_hash;
unsigned char *local_hash;
char *disk_version;
int retval;
if (disk_einfo == NULL)
return (B_TRUE);
return (B_TRUE);
return (B_TRUE);
/*
* If something goes wrong or if the on-disk version is more recent
* do not update the bootblock.
*/
return (B_FALSE);
/*
* If we got here it means that the two version strings are either
* equal or the new bootblk binary is more recent. In order to save
* some needless writes let's use the hash to determine if an update
* is really necessary.
*/
return (B_TRUE);
return (B_TRUE);
if (local_hash == NULL)
return (B_TRUE);
/*
* Failure in computing the hash may mean something wrong
* with the boot block file. Better be conservative here.
*/
return (B_FALSE);
}
return (B_FALSE);
}
return (B_TRUE);
}
char *
{
return (NULL);
}
char *
{
return (NULL);
}