static void register_manifest( const WCHAR *dll_name, const char *manifest, DWORD len, const void *dll_data, size_t dll_size ) { #ifdef __i386__ static const char current_arch[] = "x86"; #elif defined __x86_64__ static const char current_arch[] = "amd64"; #else static const char current_arch[] = "none"; #endif xmlbuf_t buffer; xmlstr_t elem, attr_name, attr_value; xmlstr_t name, version, arch, key, lang; BOOL end = FALSE, error; buffer.ptr = manifest; buffer.end = manifest + len; name.ptr = version.ptr = arch.ptr = key.ptr = lang.ptr = NULL; name.len = version.len = arch.len = key.len = lang.len = 0; while (next_xml_elem( &buffer, &elem )) { if (!xmlstr_cmp( &elem, "assemblyIdentity" )) continue; while (next_xml_attr( &buffer, &attr_name, &attr_value, &error, &end )) { if (xmlstr_cmp(&attr_name, "name")) name = attr_value; else if (xmlstr_cmp(&attr_name, "version")) version = attr_value; else if (xmlstr_cmp(&attr_name, "processorArchitecture")) arch = attr_value; else if (xmlstr_cmp(&attr_name, "publicKeyToken")) key = attr_value; else if (xmlstr_cmp(&attr_name, "language")) lang = attr_value; } if (!error && name.ptr && version.ptr && arch.ptr && key.ptr) { if (!lang.ptr) { lang.ptr = "none"; lang.len = strlen( lang.ptr ); } if (!arch.len) /* fixup the architecture */ { char *new_buffer = HeapAlloc( GetProcessHeap(), 0, len + sizeof(current_arch) ); memcpy( new_buffer, manifest, arch.ptr - manifest ); strcpy( new_buffer + (arch.ptr - manifest), current_arch ); memcpy( new_buffer + strlen(new_buffer), arch.ptr, len - (arch.ptr - manifest) ); arch.ptr = current_arch; arch.len = strlen( current_arch ); if (create_winsxs_dll( dll_name, &arch, &name, &key, &version, &lang, dll_data, dll_size )) create_manifest( &arch, &name, &key, &version, &lang, new_buffer, len + arch.len ); HeapFree( GetProcessHeap(), 0, new_buffer ); } else { if (create_winsxs_dll( dll_name, &arch, &name, &key, &version, &lang, dll_data, dll_size )) create_manifest( &arch, &name, &key, &version, &lang, manifest, len ); } } } }
Manifest *open_previous_manifest(const gchar *manifest_file, const unsigned int flags, const gchar *container, const gchar *component) { if(manifest_file == NULL) return NULL; else { g_printerr("[coordinator]: Using previous manifest: %s\n", manifest_file); return create_manifest(manifest_file, flags, container, component); } }
Manifest *open_provided_or_previous_manifest_file(const gchar *manifest_file, const gchar *coordinator_profile_path, gchar *profile, const unsigned int flags, const gchar *container, const gchar *component) { if(manifest_file == NULL) { /* If no manifest file has been provided, try opening the last deployed one */ gchar *old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, profile); if(old_manifest_file == NULL) return NULL; /* There is no previously deployed manifest */ else { /* Open the previously deployed manifest */ Manifest *manifest; g_printerr("[coordinator]: Using previous manifest: %s\n", old_manifest_file); manifest = create_manifest(old_manifest_file, flags, container, component); g_free(old_manifest_file); return manifest; } } else return create_manifest(manifest_file, flags, container, component); /* Open the provided manifest file */ }
static BOOL CALLBACK register_manifest( HMODULE module, const WCHAR *type, WCHAR *res_name, LONG_PTR arg ) { #ifdef __i386__ static const char current_arch[] = "x86"; #elif defined __x86_64__ static const char current_arch[] = "amd64"; #else static const char current_arch[] = "none"; #endif static const WCHAR manifestW[] = {'W','I','N','E','_','M','A','N','I','F','E','S','T'}; const struct dll_data *dll_data = (const struct dll_data*)arg; xmlbuf_t buffer; xmlstr_t elem, attr_name, attr_value; xmlstr_t name, version, arch, key, lang; BOOL end = FALSE, error; const char *manifest; SIZE_T len; HRSRC rsrc; if (IS_INTRESOURCE(res_name) || strncmpW( res_name, manifestW, sizeof(manifestW)/sizeof(WCHAR) )) return TRUE; rsrc = FindResourceW( module, res_name, type ); manifest = LoadResource( module, rsrc ); len = SizeofResource( module, rsrc ); buffer.ptr = manifest; buffer.end = manifest + len; name.ptr = version.ptr = arch.ptr = key.ptr = lang.ptr = NULL; name.len = version.len = arch.len = key.len = lang.len = 0; while (next_xml_elem( &buffer, &elem )) { if (!xmlstr_cmp( &elem, "assemblyIdentity" )) continue; while (next_xml_attr( &buffer, &attr_name, &attr_value, &error, &end )) { if (xmlstr_cmp(&attr_name, "name")) name = attr_value; else if (xmlstr_cmp(&attr_name, "version")) version = attr_value; else if (xmlstr_cmp(&attr_name, "processorArchitecture")) arch = attr_value; else if (xmlstr_cmp(&attr_name, "publicKeyToken")) key = attr_value; else if (xmlstr_cmp(&attr_name, "language")) lang = attr_value; } if (!error && name.ptr && version.ptr && arch.ptr && key.ptr) { if (!lang.ptr) { lang.ptr = "none"; lang.len = strlen( lang.ptr ); } if (!arch.len) /* fixup the architecture */ { char *new_buffer = HeapAlloc( GetProcessHeap(), 0, len + sizeof(current_arch) ); memcpy( new_buffer, manifest, arch.ptr - manifest ); strcpy( new_buffer + (arch.ptr - manifest), current_arch ); memcpy( new_buffer + strlen(new_buffer), arch.ptr, len - (arch.ptr - manifest) ); arch.ptr = current_arch; arch.len = strlen( current_arch ); if (create_winsxs_dll( dll_data->name, &arch, &name, &key, &version, &lang, dll_data->data, dll_data->size )) create_manifest( &arch, &name, &key, &version, &lang, new_buffer, len + arch.len ); HeapFree( GetProcessHeap(), 0, new_buffer ); } else { if (create_winsxs_dll( dll_data->name, &arch, &name, &key, &version, &lang, dll_data->data, dll_data->size )) create_manifest( &arch, &name, &key, &version, &lang, manifest, len ); } } } return TRUE; }
/* * create_object parse the object fields from the command line and call the * appropriate object creator with a table of fields filled in. */ int main( int argc, char **argv) { int ret = 0; int parse_err = 0; int index = 1; int c; char *obj_type; char *configFile = NULL; extern char *optarg; struct object_field *table; OPEN_LOG("create_object", LOG_USER); if (!my_config_load()) { LOG(LOG_ERR, "can't load configuration"); return EXIT_FAILURE; } // parse options while ((c = getopt(argc, argv, "hf:t:")) != -1) { switch (c) { case 'h': printUsage(argv); break; case 'f': configFile = optarg; break; case 't': templateFile = optarg; break; case '?': printUsage(argv); break; default: fprintf(stderr, "Illegal Option\n"); printUsage(argv); break; } } index = optind; // remaining arguments if (configFile == NULL) fprintf(stdout, "No Config file\n"); if (index >= argc) fatal(INPUT_ARG_ERR, "No Object Type"); else obj_type = argv[index++]; if (strncasecmp(obj_type, "CERT", strlen("CERT")) == 0) { table = get_cert_field_table(); if (configFile != NULL) if (parse_config(configFile, table) != 0) { warn(INPUT_ARG_ERR, parse_errstr); parse_err = 1; } // parse and validate arguments, exit if either or both fail if (parse_args(argc, argv, index, table) != 0) { warn(INPUT_ARG_ERR, parse_errstr); parse_err = 1; } if (validate_table(table, validate_errstr, sizeof(validate_errstr)) != 0) fatal(MISSING_FIELDS, validate_errstr); // if no validation error but we did have a parse err - exit if (parse_err) { config_unload(); exit(INPUT_ARG_ERR); } ret = create_cert(table); // fprintf(stdout,"return from creating certificate %d\n", ret); } else if (strncasecmp(obj_type, "CRL", strlen("CRL")) == 0) { table = get_crl_field_table(); if (configFile != NULL) if (parse_config(configFile, table) != 0) { warn(INPUT_ARG_ERR, parse_errstr); parse_err = 1; } if (parse_args(argc, argv, index, table) != 0) { warn(INPUT_ARG_ERR, parse_errstr); parse_err = 1; } if (validate_table(table, validate_errstr, sizeof(validate_errstr)) != 0) fatal(MISSING_FIELDS, validate_errstr); // if no validation error but we did have a parse err - exit if (parse_err) { config_unload(); exit(INPUT_ARG_ERR); } ret = create_crl(table); } else if (strncasecmp(obj_type, "ROA", strlen("ROA")) == 0) { table = get_roa_field_table(); if (configFile != NULL) if (parse_config(configFile, table) != 0) { warn(INPUT_ARG_ERR, parse_errstr); parse_err = 1; } if (parse_args(argc, argv, index, table) != 0) fatal(INPUT_ARG_ERR, parse_errstr); if (validate_table(table, validate_errstr, sizeof(validate_errstr)) != 0) fatal(MISSING_FIELDS, validate_errstr); ret = create_roa(table); } else if (strncasecmp(obj_type, "MANIFEST", strlen("MANIFEST")) == 0) { table = get_man_field_table(); if (configFile != NULL) if (parse_config(configFile, table) != 0) { warn(INPUT_ARG_ERR, parse_errstr); parse_err = 1; } // parse arguments and validate table if (parse_args(argc, argv, index, table) != 0) warn(INPUT_ARG_ERR, parse_errstr); if (validate_table(table, validate_errstr, sizeof(validate_errstr)) != 0) fatal(MISSING_FIELDS, validate_errstr); ret = create_manifest(table); } else fatal(INPUT_ARG_ERR, argv[1]); config_unload(); exit(ret); }
int activate_system(const gchar *new_manifest, const gchar *old_manifest, const gchar *coordinator_profile_path, gchar *profile, const gboolean no_upgrade, const gboolean no_rollback, const gboolean dry_run) { Manifest *manifest = create_manifest(new_manifest, MANIFEST_ACTIVATION_FLAG, NULL, NULL); if(manifest == NULL) { g_printerr("[coordinator]: Error opening manifest file!\n"); return 1; } else { TransitionStatus status; gchar *old_manifest_file; GPtrArray *old_activation_mappings; /* If no previous configuration is given, check whether we have one in the coordinator profile, otherwise use the given one */ if(old_manifest == NULL) old_manifest_file = determine_previous_manifest_file(coordinator_profile_path, profile); else old_manifest_file = g_strdup(old_manifest); /* If we have an old configuration -> open it */ if(!no_upgrade && old_manifest_file != NULL) { g_print("[coordinator]: Doing an upgrade from previous manifest file: %s\n", old_manifest_file); old_activation_mappings = create_activation_array(old_manifest_file); } else { g_print("[coordinator]: Doing an installation from scratch\n"); old_activation_mappings = NULL; } /* Override SIGINT's behaviour to allow stuff to be rollbacked in case of an interruption */ set_flag_on_interrupt(); /* Execute transition */ g_print("[coordinator]: Executing the transition to the new deployment state\n"); if((status = transition(manifest->activation_array, old_activation_mappings, manifest->target_array, no_rollback, dry_run)) == TRANSITION_SUCCESS) g_printerr("[coordinator]: The new configuration has been successfully activated!\n"); else { g_printerr("[coordinator]: ERROR: Transition phase execution failed!\n"); if(old_manifest_file != NULL && status == TRANSITION_ROLLBACK_FAILED) { g_printerr("The rollback failed! This means the system is now inconsistent! Please\n"); g_printerr("manually diagnose the errors before doing another redeployment!\n\n"); g_printerr("When the problems have been solved, the rollback can be triggered again, by\n"); g_printerr("running:\n\n"); g_printerr("$ disnix-activate --no-rollback -p %s ", profile); if(coordinator_profile_path != NULL) g_printerr("--coordinator-profile-path %s ", coordinator_profile_path); g_printerr("-o %s %s\n\n", new_manifest, old_manifest_file); } } /* Cleanup */ g_free(old_manifest_file); delete_manifest(manifest); delete_activation_array(old_activation_mappings); /* Return the transition status */ return status; } }