mirror of
https://github.com/NVIDIA/nvidia-installer.git
synced 2025-07-23 02:13:00 +02:00
709 lines
23 KiB
C
709 lines
23 KiB
C
/*
|
|
* gcc mkprecompiled.c -o mkprecompiled -Wall -g
|
|
*
|
|
* mkprecompiled - this program packages up a precompiled kernel
|
|
* module interface with a list of unresolved symbols in the kernel
|
|
* module.
|
|
*
|
|
* normally, this would be done much more simply with a perl or shell
|
|
* script, but I've implemented it in C because we don't want the
|
|
* installer to rely upon any system utilities that it doesn't
|
|
* absolutely need.
|
|
*
|
|
* commandline options:
|
|
*
|
|
* -i, --interface=<filename>
|
|
* -o, --output=<filename>
|
|
* -u, --unpack=<filename>
|
|
* -d, --description=<kernel description>
|
|
*
|
|
* There is nothing specific to the NVIDIA graphics driver in this
|
|
* program, so it should be usable for the nforce drivers, for
|
|
* example.
|
|
*/
|
|
|
|
#define BINNAME "mkprecompiled"
|
|
#define NV_LINE_LEN 256
|
|
#define NV_VERSION_LEN 4096
|
|
#define PROC_MOUNT_POINT "/proc"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
#include <ctype.h>
|
|
#include <stdarg.h>
|
|
#include <inttypes.h>
|
|
|
|
#include <nvgetopt.h>
|
|
|
|
typedef unsigned int uint32;
|
|
typedef unsigned char uint8;
|
|
|
|
enum {
|
|
PACK = 'p',
|
|
UNPACK = 'u',
|
|
INFO = 'i',
|
|
MATCH = 'm',
|
|
};
|
|
|
|
/*
|
|
* Options structure
|
|
*/
|
|
|
|
typedef struct {
|
|
int action;
|
|
char *package_file;
|
|
char *output_directory;
|
|
char *description;
|
|
char *proc_version_string;
|
|
char *proc_mount_point;
|
|
char *version;
|
|
int num_files;
|
|
struct __precompiled_file_info *new_files;
|
|
struct __precompiled_info *package;
|
|
} Options;
|
|
|
|
|
|
#include "common-utils.h"
|
|
#include "crc.h"
|
|
#include "precompiled.h"
|
|
|
|
|
|
/*
|
|
* XXX hack to resolve symbols used by crc.c and precompiled.c
|
|
*/
|
|
|
|
void ui_warn(Options *op, const char *fmt, ...);
|
|
|
|
void ui_warn(Options *op, const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
vfprintf(stderr, fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void ui_expert(Options *op, const char *fmt, ...);
|
|
|
|
void ui_expert(Options *op, const char *fmt, ...)
|
|
{
|
|
}
|
|
|
|
void ui_error(Options *op, const char *fmt, ...);
|
|
|
|
void ui_error(Options *op, const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
vfprintf(stderr, fmt, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
void ui_log(Options *op, const char *fmt, ...);
|
|
|
|
void ui_log(Options *op, const char *fmt, ...)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* print_help()
|
|
*/
|
|
|
|
static void print_help(void)
|
|
{
|
|
printf("\n%s: pack/unpack precompiled files, and get information about\n"
|
|
"existing precompiled file packages.\n\n"
|
|
"USAGE: <action> <package-file> [options] \n\n", BINNAME);
|
|
|
|
printf("<action> may be one of:\n\n"
|
|
" -p | --pack add files to a package\n"
|
|
" -u | --unpack unpack files from a package\n"
|
|
" -i | --info display information about a package\n"
|
|
" -m | --match check if a package matches the running kernel\n"
|
|
" -h | --help print this help text and exit\n\n"
|
|
"<package-file> is the package file to pack/unpack/test. It must be\n"
|
|
"an existing, valid package file for the --unpack, --info, and\n"
|
|
"--match actions. For the --pack action, if <package-file> does not\n"
|
|
"exist, it is created; if it exists but is not a valid package file,\n"
|
|
"it is overwritten; and if it exists and is a valid package file,\n"
|
|
"files will be added to the existing package.\n\n"
|
|
"--pack options:\n"
|
|
" -v | --driver-version (REQUIRED for new packages)\n"
|
|
" The version of the packaged components.\n"
|
|
" -P | --proc-version-string (RECOMMENDED for new packages)\n"
|
|
" The kernel version, as reported by '/proc/version', for the\n"
|
|
" target kernel. Default: the contents of the '/proc/version'\n"
|
|
" file on the current system.\n"
|
|
" -d | --description (RECOMMENDED for new packages)\n"
|
|
" A human readable description of the package.\n"
|
|
" --kernel-interface <file> --linked-module-name <module-name>\\\n"
|
|
" --core-object-name <core-name>\\\n"
|
|
" [ --linked-module <linked-kmod-file> \\\n"
|
|
" --signed-module <signed-kmod-file> ]\\\n"
|
|
" [ --target-directory <target-directory> ]\n"
|
|
" Pack <file> as a precompiled kernel interface.\n"
|
|
" <module-name> specifies the name of the kernel module file\n"
|
|
" that is produced by linking the precompiled kernel interface\n"
|
|
" with a separate precompiled core object file. <core-name>\n"
|
|
" specifies the name of the core object file that is linked\n"
|
|
" together with the precompiled interface to produce the final\n"
|
|
" kernel module.\n"
|
|
" A detached module signature may be produced by specifying\n"
|
|
" both the --linked-module and --signed-module options.\n"
|
|
" <linked-kmod-file> is a linked .ko file that is the result\n"
|
|
" of linking the precompiled interface with the remaining\n"
|
|
" object file(s) required to produce the finished module, and\n"
|
|
" <signed-kmod-file> is a copy of <linked-kmod-file> which an\n"
|
|
" appended module signature. In order for the signature to be\n"
|
|
" correctly applied on the target system, the linking should\n"
|
|
" be performed with the same linker and flags that will be\n"
|
|
" used on the target system.\n"
|
|
" A target directory for unpacking the interface may be\n"
|
|
" specified with the --target-directory option.\n"
|
|
" <target-directory> is the name of the directory where the\n"
|
|
" unpacked interface will be written.\n"
|
|
" The --linked-module and --signed-module options must be\n"
|
|
" given after the --kernel-interface option for the kernel\n"
|
|
" interface file with which they are associated, and before\n"
|
|
" any additional --kernel-interface or --kernel-module files.\n"
|
|
" --kernel-module <file> [ --signed ]\\\n"
|
|
" [ --target-directory <target-directory> ]\n"
|
|
" Pack <file> as a precompiled kernel module. The --signed\n"
|
|
" option specifies that <file> includes a module signature.\n"
|
|
" The --signed option must be given after the --kernel-module\n"
|
|
" option for the kernel module with which it is associated,\n"
|
|
" and before any additional --kernel-interface or\n"
|
|
" --kernel-module files.\n\n"
|
|
" If --driver-version, --proc-version-string, or --description\n"
|
|
" are given with an existing package file, the values in that\n"
|
|
" package file will be updated with new ones. At least one file\n"
|
|
" must be given with either --kernel-interface or --kernel-module\n"
|
|
" when using the --pack option.\n\n"
|
|
"--unpack options:\n"
|
|
" -o | --output-directory\n"
|
|
" The target directory where files will be unpacked. Default:\n"
|
|
" unpack files in the current directory.\n\n"
|
|
"Additional options:\n"
|
|
" --proc-mount-point\n"
|
|
" The procfs mount point on the current system, where the \n"
|
|
" '/proc/version' file may be found. Used by the --match\n"
|
|
" action, as well as to supply the default value of the\n"
|
|
" --proc-version-string option of the --pack action.\n"
|
|
" Default value: '/proc'\n");
|
|
|
|
} /* print_help() */
|
|
|
|
|
|
enum {
|
|
PROC_MOUNT_POINT_OPTION = 1024,
|
|
KERNEL_INTERFACE_OPTION,
|
|
KERNEL_MODULE_OPTION,
|
|
SIGNED_FILE_OPTION,
|
|
LINKED_MODULE_OPTION,
|
|
LINKED_AND_SIGNED_MODULE_OPTION,
|
|
LINKED_MODULE_NAME_OPTION,
|
|
CORE_OBJECT_NAME_OPTION,
|
|
TARGET_DIRECTORY_OPTION
|
|
};
|
|
|
|
|
|
static void grow_file_array(Options *op, int *array_size)
|
|
{
|
|
if (op->num_files < 0) {
|
|
op->num_files = 0;
|
|
}
|
|
|
|
if (op->num_files >= *array_size) {
|
|
*array_size *= 2;
|
|
op->new_files = nvrealloc(op->new_files,
|
|
sizeof(PrecompiledFileInfo) * *array_size);
|
|
}
|
|
}
|
|
|
|
|
|
static uint32 file_type_from_option(int option) {
|
|
switch (option) {
|
|
case KERNEL_INTERFACE_OPTION:
|
|
return PRECOMPILED_FILE_TYPE_INTERFACE;
|
|
case KERNEL_MODULE_OPTION:
|
|
return PRECOMPILED_FILE_TYPE_MODULE;
|
|
default:
|
|
fprintf(stderr, "Unrecognized file type!");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
static void check_file_option_validity(Options *op, const char *option_name)
|
|
{
|
|
if (op->num_files < 0) {
|
|
fprintf(stderr, "The --%s option cannot be specified before a file "
|
|
"name.\n", option_name);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
static int create_detached_signature(Options *op, PrecompiledFileInfo *file,
|
|
const char *linked_module,
|
|
const char *signed_module)
|
|
{
|
|
if (file->type != PRECOMPILED_FILE_TYPE_INTERFACE) {
|
|
return TRUE;
|
|
} else if (linked_module && signed_module) {
|
|
struct stat st;
|
|
|
|
if (stat(linked_module, &st) != 0) {
|
|
fprintf(stderr, "Unable to stat the linked kernel module file '%s'."
|
|
"\n", linked_module);
|
|
return FALSE;
|
|
}
|
|
|
|
file->linked_module_crc = compute_crc(op, linked_module);
|
|
file->attributes |= PRECOMPILED_ATTR(LINKED_MODULE_CRC);
|
|
|
|
file->signature_size = byte_tail(signed_module, st.st_size,
|
|
&(file->signature));
|
|
|
|
if (file->signature_size > 0 && file->signature != NULL) {
|
|
file->attributes |= PRECOMPILED_ATTR(DETACHED_SIGNATURE);
|
|
return TRUE;
|
|
} else {
|
|
fprintf(stderr, "Failed to create a detached signature from signed "
|
|
"kernel module '%s'.\n", signed_module);
|
|
}
|
|
|
|
} else if (linked_module || signed_module) {
|
|
fprintf(stderr, "Both --linked-module and --signed-module must be "
|
|
"specified to create a detached signature for precompiled "
|
|
"kernel interface file '%s'.\n", file->name);
|
|
} else {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static void set_action(Options *op, int action)
|
|
{
|
|
if (op->action) {
|
|
fprintf(stderr, "Invalid command line; multiple actions cannot be "
|
|
"specified at the same time.\n");
|
|
exit(1);
|
|
}
|
|
|
|
op->action = action;
|
|
}
|
|
|
|
static void pack_a_file(Options *op, PrecompiledFileInfo *file,
|
|
char *name, uint32 type, char **linked_name,
|
|
char **core_name, char **target_directory,
|
|
char **linked_module_file, char **signed_module_file)
|
|
{
|
|
if (!*target_directory) {
|
|
*target_directory = nvstrdup("");
|
|
}
|
|
|
|
switch(type) {
|
|
case PRECOMPILED_FILE_TYPE_INTERFACE:
|
|
if (*linked_name == NULL || *core_name == NULL) {
|
|
fprintf(stderr, "Each kernel interface file must have both the "
|
|
"--linked-module-name and --core-object-name options set "
|
|
"in order to be added to a package.\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (!precompiled_read_interface(file, name, *linked_name, *core_name,
|
|
*target_directory)) {
|
|
fprintf(stderr, "Failed to read kernel interface '%s'.\n", name);
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case PRECOMPILED_FILE_TYPE_MODULE:
|
|
if (!precompiled_read_module(file, name, *target_directory)) {
|
|
fprintf(stderr, "Failed to read kernel module '%s'.\n", name);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
exit(1);
|
|
}
|
|
nvfree(name);
|
|
|
|
if (!create_detached_signature(op, file, *linked_module_file,
|
|
*signed_module_file)) {
|
|
exit(1);
|
|
}
|
|
|
|
op->num_files++;
|
|
|
|
nvfree(*linked_name);
|
|
nvfree(*core_name);
|
|
nvfree(*target_directory);
|
|
nvfree(*linked_module_file);
|
|
nvfree(*signed_module_file);
|
|
*linked_name = *core_name = *target_directory = *linked_module_file =
|
|
*signed_module_file = NULL;
|
|
}
|
|
|
|
/*
|
|
* parse_commandline() - parse the commandline arguments. do some
|
|
* trivial validation, and return an initialized malloc'ed Options
|
|
* structure.
|
|
*/
|
|
|
|
static Options *parse_commandline(int argc, char *argv[])
|
|
{
|
|
Options *op;
|
|
int c, file_array_size = 16;
|
|
uint32 type = 0;
|
|
PrecompiledFileInfo *file = NULL;
|
|
char *strval, *signed_mod = NULL, *linked_mod = NULL, *filename = NULL,
|
|
*linked_name = NULL, *core_name = NULL, *target_directory = NULL;
|
|
char see_help[1024];
|
|
|
|
static const NVGetoptOption long_options[] = {
|
|
{ "pack", PACK, NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "unpack", UNPACK, NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "info", INFO, NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "match", MATCH, NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "help", 'h', 0, NULL, NULL },
|
|
{ "description", 'd', NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "output-directory", 'o', NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "driver-version", 'v', NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "proc-version-string", 'P', NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "proc-mount-point", PROC_MOUNT_POINT_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "kernel-interface", KERNEL_INTERFACE_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "kernel-module", KERNEL_MODULE_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "signed", SIGNED_FILE_OPTION,
|
|
0, NULL, NULL },
|
|
{ "linked-module", LINKED_MODULE_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "signed-module", LINKED_AND_SIGNED_MODULE_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "linked-module-name", LINKED_MODULE_NAME_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "core-object-name", CORE_OBJECT_NAME_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ "target-directory", TARGET_DIRECTORY_OPTION,
|
|
NVGETOPT_STRING_ARGUMENT, NULL, NULL },
|
|
{ NULL, 0, 0, NULL, NULL }
|
|
};
|
|
|
|
snprintf(see_help, sizeof(see_help), "Please run `%s --help` for usage "
|
|
"information.\n", argv[0]);
|
|
see_help[sizeof(see_help) - 1] = '\0';
|
|
|
|
op = (Options *) nvalloc(sizeof(Options));
|
|
op->new_files = nvalloc(sizeof(PrecompiledFileInfo) * file_array_size);
|
|
op->num_files = -1;
|
|
|
|
op->proc_mount_point = PROC_MOUNT_POINT;
|
|
|
|
while (1) {
|
|
c = nvgetopt(argc, argv, long_options, &strval,
|
|
NULL, /* boolval */
|
|
NULL, /* intval */
|
|
NULL, /* doubleval */
|
|
NULL /* disable_val */);
|
|
|
|
if (c == -1)
|
|
break;
|
|
|
|
switch(c) {
|
|
case PACK: case UNPACK: case INFO: case MATCH:
|
|
set_action(op, c);
|
|
op->package_file = strval;
|
|
break;
|
|
|
|
case 'h': print_help(); exit(0); break;
|
|
case 'f': op->package_file = strval; break;
|
|
case 'd': op->description = strval; break;
|
|
case 'o': op->output_directory = strval; break;
|
|
case 'v': op->version = strval; break;
|
|
case 'P': op->proc_version_string = strval; break;
|
|
case PROC_MOUNT_POINT_OPTION: op->proc_mount_point = strval; break;
|
|
|
|
case KERNEL_INTERFACE_OPTION: case KERNEL_MODULE_OPTION:
|
|
|
|
grow_file_array(op, &file_array_size);
|
|
|
|
if (file) {
|
|
pack_a_file(op, file, filename, type, &linked_name, &core_name,
|
|
&target_directory, &linked_mod, &signed_mod);
|
|
}
|
|
|
|
file = op->new_files + op->num_files;
|
|
filename = strval;
|
|
type = file_type_from_option(c);
|
|
|
|
break;
|
|
|
|
case SIGNED_FILE_OPTION:
|
|
|
|
check_file_option_validity(op, "signed");
|
|
|
|
/*
|
|
* for interfaces, signedness is implied by the presence of a linked
|
|
* module crc and a detached signature, so only set the signed file
|
|
* attribute in the case of a precompiled kernel module.
|
|
*/
|
|
|
|
if (type == PRECOMPILED_FILE_TYPE_MODULE) {
|
|
file->attributes |= PRECOMPILED_ATTR(EMBEDDED_SIGNATURE);
|
|
}
|
|
|
|
break;
|
|
|
|
case LINKED_MODULE_OPTION:
|
|
|
|
check_file_option_validity(op, "linked-module");
|
|
linked_mod = strval;
|
|
|
|
break;
|
|
|
|
case LINKED_AND_SIGNED_MODULE_OPTION:
|
|
|
|
check_file_option_validity(op, "signed-module");
|
|
signed_mod = strval;
|
|
|
|
break;
|
|
|
|
case LINKED_MODULE_NAME_OPTION:
|
|
|
|
check_file_option_validity(op, "linked-module-name");
|
|
linked_name = strval;
|
|
|
|
break;
|
|
|
|
case CORE_OBJECT_NAME_OPTION:
|
|
|
|
check_file_option_validity(op, "core-object-name");
|
|
core_name = strval;
|
|
|
|
break;
|
|
|
|
case TARGET_DIRECTORY_OPTION:
|
|
|
|
check_file_option_validity(op, "target-directory");
|
|
target_directory = strval;
|
|
|
|
break;
|
|
|
|
default:
|
|
fprintf (stderr, "Invalid commandline; %s", see_help);
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
|
|
/* validate options */
|
|
|
|
if (!op->action) {
|
|
fprintf(stderr, "No action specified; one of --pack, --unpack, --info, "
|
|
"or --match options must be given. %s", see_help);
|
|
exit(1);
|
|
}
|
|
|
|
switch (op->action) {
|
|
case PACK:
|
|
if (file) {
|
|
pack_a_file(op, file, filename, type, &linked_name, &core_name,
|
|
&target_directory, &linked_mod, &signed_mod);
|
|
}
|
|
|
|
if (op->num_files < 1) {
|
|
fprintf(stderr, "At least one file to pack must be specified "
|
|
"when using the --pack option; %s", see_help);
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case UNPACK:
|
|
if (!op->output_directory) {
|
|
op->output_directory = ".";
|
|
}
|
|
break;
|
|
|
|
case INFO: case MATCH: default: /* XXX should never hit default case */
|
|
break;
|
|
}
|
|
|
|
op->package = get_precompiled_info(op, op->package_file, NULL, NULL, NULL);
|
|
|
|
if (!op->package && op->action != PACK) {
|
|
fprintf(stderr, "Unable to read package file '%s'.\n",
|
|
op->package_file);
|
|
exit(1);
|
|
}
|
|
|
|
return op;
|
|
|
|
} /* parse_commandline() */
|
|
|
|
|
|
|
|
|
|
/*
|
|
* check_match() - read /proc/version, and do a strcmp with str.
|
|
* Returns 1 if the strings match, 0 if they don't match.
|
|
*/
|
|
|
|
static int check_match(Options *op, char *str)
|
|
{
|
|
int ret = 0;
|
|
char *version = read_proc_version(op, op->proc_mount_point);
|
|
|
|
if (strcmp(version, str) == 0) {
|
|
ret = 1;
|
|
printf("kernel interface matches.\n");
|
|
} else {
|
|
ret = 0;
|
|
printf("kernel interface doesn't match.\n");
|
|
}
|
|
|
|
free(version);
|
|
|
|
return ret;
|
|
|
|
} /* check_match() */
|
|
|
|
|
|
|
|
/*
|
|
* program entry point
|
|
*/
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
Options *op;
|
|
int ret = 1;
|
|
|
|
op = parse_commandline(argc, argv);
|
|
|
|
|
|
switch (op->action) {
|
|
int i;
|
|
|
|
case PACK:
|
|
if (!op->package) {
|
|
if (!op->version) {
|
|
fprintf (stderr, "The --driver-version option must be specified "
|
|
"when using the --pack option to create a new package; "
|
|
"Please run `%s --help` for usage information.\n",
|
|
argv[0]);
|
|
exit (1);
|
|
}
|
|
|
|
op->package = nvalloc(sizeof(PrecompiledInfo));
|
|
|
|
op->package->description = op->description ? op->description :
|
|
nvstrdup("");
|
|
op->package->proc_version_string =
|
|
op->proc_version_string ?
|
|
op->proc_version_string :
|
|
read_proc_version(op, op->proc_mount_point);
|
|
op->package->version = op->version;
|
|
}
|
|
|
|
precompiled_append_files(op->package, op->new_files, op->num_files);
|
|
|
|
if (precompiled_pack(op->package, op->package_file)) {
|
|
ret = 0;
|
|
} else {
|
|
fprintf(stderr, "An error occurred while writing the package "
|
|
"file '%s'.\n", op->package_file);
|
|
}
|
|
|
|
break;
|
|
|
|
case UNPACK:
|
|
if (precompiled_unpack(op, op->package, op->output_directory)) {
|
|
ret = 0;
|
|
} else {
|
|
fprintf(stderr, "An error occurred while unpacking the package "
|
|
"file '%s' to '%s'.\n", op->package_file,
|
|
op->output_directory);
|
|
}
|
|
break;
|
|
|
|
case INFO:
|
|
|
|
printf("description: %s\n", op->package->description);
|
|
printf("version: %s\n", op->package->version);
|
|
printf("proc version: %s\n", op->package->proc_version_string);
|
|
printf("number of files: %d\n\n", op->package->num_files);
|
|
|
|
for (i = 0; i < op->package->num_files; i++) {
|
|
PrecompiledFileInfo *file = op->package->files + i;
|
|
const char **attrs, **attr;
|
|
|
|
attrs = precompiled_file_attribute_names(file->attributes);
|
|
|
|
printf("file %d:\n", i + 1);
|
|
printf(" name: '%s'\n", file->name);
|
|
printf(" type: %s\n",
|
|
precompiled_file_type_name(file->type));
|
|
printf(" attributes: ");
|
|
|
|
for (attr = attrs; *attr; attr++) {
|
|
if (attr > attrs) {
|
|
printf(", ");
|
|
}
|
|
printf("%s", *attr);
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
printf(" size: %d bytes\n", file->size);
|
|
printf(" crc: %" PRIu32 "\n", file->crc);
|
|
printf(" target directory: %s\n", file->target_directory);
|
|
|
|
if (file->type == PRECOMPILED_FILE_TYPE_INTERFACE) {
|
|
printf(" core object name: %s\n", file->core_object_name);
|
|
printf(" linked module name: %s\n", file->linked_module_name);
|
|
if (file->signature_size) {
|
|
printf(" linked module crc: %" PRIu32 "\n",
|
|
file->linked_module_crc);
|
|
printf(" signature size: %d\n", file->signature_size);
|
|
}
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
ret = 0;
|
|
break;
|
|
|
|
case MATCH:
|
|
|
|
ret = check_match(op, op->package->proc_version_string);
|
|
break;
|
|
|
|
default: /* XXX should never get here */ break;
|
|
|
|
}
|
|
|
|
free_precompiled(op->package);
|
|
|
|
return ret;
|
|
|
|
} /* main() */
|