/*
* Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
* Copyright (C) 2008 Red Hat, Inc
- * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ * Copyright (C) 2009, 2011 J. Ali Harlow <ali@juiblex.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
YUM_STATE_PROVIDES,
YUM_STATE_OBSOLETES,
YUM_STATE_CONFLICTS,
+ YUM_STATE_SKIPPING_PACKAGE,
YUM_STATE_FILE
};
uint32_t pre, relation, flags;
int i;
+ if (ctx->state == YUM_STATE_SKIPPING_PACKAGE)
+ return;
+
if (strcmp(name, "metadata") == 0) {
for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "packages") == 0)
}
razor_build_evr(buffer, sizeof buffer, epoch, version, release);
- razor_importer_begin_package(ctx->importer,
- ctx->name, buffer, ctx->arch);
+ if (!strcmp(ctx->arch, "noarch") ||
+ !strcmp(ctx->arch, razor_system_arch())) {
+ razor_importer_begin_package(ctx->importer, ctx->name,
+ buffer, ctx->arch);
+ } else
+ ctx->state = YUM_STATE_SKIPPING_PACKAGE;
} else if (strcmp(name, "summary") == 0) {
ctx->p = ctx->summary;
ctx->state = YUM_STATE_SUMMARY;
}
if (strcmp(name, "package") == 0) {
- razor_importer_add_details(ctx->importer, ctx->summary,
- ctx->description, ctx->url,
- ctx->license);
+ if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
+ razor_importer_add_details(ctx->importer, ctx->summary,
+ ctx->description, ctx->url,
+ ctx->license);
XML_StopParser(ctx->current_parser, XML_TRUE);
ctx->current_parser = ctx->filelists_parser;
const char *pkg, *pkgid;
int i;
- if (strcmp(name, "package") == 0) {
+ if (strcmp(name, "package") == 0 &&
+ ctx->state != YUM_STATE_SKIPPING_PACKAGE) {
pkg = NULL;
pkgid = NULL;
for (i = 0; atts[i]; i += 2) {
"mismatch for %s: %s vs %s",
pkg, pkgid, ctx->pkgid);
} else if (strcmp(name, "file") == 0) {
- ctx->state = YUM_STATE_FILE;
+ if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
+ ctx->state = YUM_STATE_FILE;
ctx->p = ctx->buffer;
}
}
{
struct yum_context *ctx = data;
- ctx->state = YUM_STATE_BEGIN;
if (strcmp(name, "package") == 0) {
XML_StopParser(ctx->current_parser, XML_TRUE);
ctx->current_parser = ctx->primary_parser;
- razor_importer_finish_package(ctx->importer);
- } else if (strcmp(name, "file") == 0)
- razor_importer_add_file(ctx->importer, ctx->buffer);
+ if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
+ razor_importer_finish_package(ctx->importer);
+ ctx->state = YUM_STATE_BEGIN;
+ } else if (strcmp(name, "file") == 0) {
+ if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
+ razor_importer_add_file(ctx->importer, ctx->buffer);
+ }
+ if (ctx->state != YUM_STATE_SKIPPING_PACKAGE)
+ ctx->state = YUM_STATE_BEGIN;
+}
+static int plover_system_arch_is_x86(void)
+{
+ const char *arch=razor_system_arch();
+ if (!arch || arch[0]!='i' || arch[1]<'3' || arch[1]>'6')
+ return 0;
+ else
+ return !strcmp(arch+2,"86");
}
#define XML_BUFFER_SIZE 4096
{
struct yum_context ctx;
void *buf;
- int len, ret;
+ int len;
gzFile primary, filelists;
XML_ParsingStatus status;
+ struct razor_set *set;
ctx.importer = razor_importer_create();
ctx.state = YUM_STATE_BEGIN;
XML_GetParsingStatus(ctx.current_parser, &status);
switch (status.parsing) {
case XML_SUSPENDED:
- ret = XML_ResumeParser(ctx.current_parser);
+ XML_ResumeParser(ctx.current_parser);
break;
case XML_PARSING:
case XML_INITIALIZED:
gzclose(primary);
gzclose(filelists);
- return razor_importer_finish(ctx.importer);
+ set = razor_importer_finish(ctx.importer);
+#if RAZOR_HEADER_VERSION_MIN <= 1
+ /*
+ * Header version 1 is supported by plover v0.3 and is used on
+ * 32-bit intel machines which allows the setup and update
+ * applications from v0.3 to work. On other machines, we don't
+ * want these old applications to work (since they would do
+ * the wrong thing) and so we use the current header version
+ * which they don't support.
+ */
+ if (plover_system_arch_is_x86())
+ razor_set_set_header_version(set, 1);
+#endif
+
+ return set;
}
/*
* Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
* Copyright (C) 2008 Red Hat, Inc
- * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
+ * Copyright (C) 2009, 2011 J. Ali Harlow <ali@juiblex.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
struct razor_set *plover_relocate_packages(struct razor_set *set,
- const char *base,struct razor_relocations *relocations)
+ struct razor_atomic *atomic,const char *base,
+ struct razor_relocations *relocations)
{
struct razor_importer *importer;
struct razor_property_iterator *prop_iter;
struct razor_package *package;
struct razor_property *property;
struct razor_rpm *rpm;
+ struct razor_set *new;
const char *name,*version,*arch,*summary,*desc,*url,*license;
char *s,*file;
uint32_t flags;
s=rpm_filename(name,version,arch);
file=plover_strconcat(base,"/rpms/",s,NULL);
free(s);
- rpm=razor_rpm_open(file);
+ rpm=razor_rpm_open(file,atomic);
+ free(file);
if (!rpm)
{
- fprintf(stderr,"failed to open rpm %s\n",file);
razor_package_iterator_destroy(pkg_iter);
razor_importer_destroy(importer);
- free(file);
return NULL;
}
- free(file);
razor_relocations_set_rpm(relocations,rpm);
razor_rpm_close(rpm);
razor_importer_begin_package(importer,name,version,arch);
razor_importer_finish_package(importer);
}
razor_package_iterator_destroy(pkg_iter);
- return razor_importer_finish(importer);
+ new=razor_importer_finish(importer);
+ if (new)
+ razor_set_set_header_version(new,razor_set_get_header_version(set));
+ return new;
}
-int plover_run_transaction(struct razor_transaction *trans,const char *base,
- const char *install_root,struct razor_set *system,struct razor_set *next,
- struct razor_relocations *relocations)
+int plover_run_transaction(struct razor_transaction *trans,
+ struct razor_install_iterator *ii,const char *base,const char *install_root,
+ struct razor_set *system,struct razor_set *next,struct razor_atomic *atomic,
+ struct razor_relocations *relocations,enum razor_stage_type stage)
{
- struct razor_install_iterator *ii;
struct razor_package *package;
enum razor_install_action action;
struct razor_rpm *rpm;
const char *name,*version,*arch;
char *s,*file;
int count;
- ii=razor_set_create_install_iterator(system,next);
- printf("Running Transaction\n");
+ razor_install_iterator_rewind(ii);
+ switch(stage)
+ {
+ case RAZOR_STAGE_SCRIPTS_PRE:
+ printf("Running pre-transaction scripts\n");
+ break;
+ case RAZOR_STAGE_FILES:
+ printf("Running Transaction\n");
+ break;
+ case RAZOR_STAGE_SCRIPTS_POST:
+ printf("Running post-transaction scripts\n");
+ break;
+ default:
+ /* Keep the compiler happy */
+ break;
+ }
while (razor_install_iterator_next(ii,&package,&action,&count))
{
if (action==RAZOR_INSTALL_ACTION_REMOVE)
{
razor_package_get_details(system,package,RAZOR_DETAIL_NAME,&name,
RAZOR_DETAIL_LAST);
- printf(" Removing : %s ",name);
- if (razor_package_remove(system,next,package,install_root,count)<0)
- printf(
- "\nWarning: one or more errors occurred while removing %s",
- name);
- printf("\n");
+ if (stage==RAZOR_STAGE_FILES)
+ printf(" Removing : %s ",name);
+ razor_package_remove(system,next,atomic,package,install_root,
+ count,stage);
+ if (stage==RAZOR_STAGE_FILES)
+ printf("\n");
}
else
{
razor_package_get_details(next,package,RAZOR_DETAIL_NAME,&name,
RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
RAZOR_DETAIL_LAST);
- printf(" Installing : %s ",name);
s=rpm_filename(name,version,arch);
file=plover_strconcat(base,"/rpms/",s,NULL);
free(s);
- rpm=razor_rpm_open(file);
+ rpm=razor_rpm_open(file,atomic);
+ free(file);
if (!rpm)
- {
- fprintf(stderr,"failed to open rpm %s\n",file);
- free(file);
- razor_install_iterator_destroy(ii);
return -1;
- }
+ if (stage==RAZOR_STAGE_FILES)
+ printf(" Installing : %s ",name);
if (relocations)
razor_rpm_set_relocations(rpm,relocations);
razor_transaction_fixup_package(trans,package,rpm);
- if (razor_rpm_install(rpm,install_root,1)<0)
- {
- fprintf(stderr,"failed to install rpm %s\n",file);
- razor_rpm_close(rpm);
- free(file);
- razor_install_iterator_destroy(ii);
- return -1;
- }
+ razor_rpm_install(rpm,atomic,install_root,1,stage);
razor_rpm_close(rpm);
- free(file);
- printf("\n");
+ if (stage==RAZOR_STAGE_FILES)
+ printf("\n");
}
+ if (razor_atomic_in_error_state(atomic))
+ return -1;
}
- razor_install_iterator_destroy(ii);
return 0;
}
+/*
+ * Note: plover_commit_transaction() takes ownership of root which should
+ * not be used after it returns.
+ */
+int plover_commit_transaction(struct razor_transaction *trans,const char *base,
+ const char *install_root,struct razor_root *root,struct razor_atomic *atomic,
+ struct razor_relocations *relocations)
+{
+ int retval;
+ struct razor_set *next,*system;
+ struct razor_install_iterator *ii;
+ razor_transaction_resolve(trans);
+ if (razor_transaction_describe(trans)>0)
+ {
+ razor_root_close(root);
+ return -1;
+ }
+ next=razor_transaction_commit(trans);
+ system=razor_root_get_system_set(root);
+ ii=razor_set_create_install_iterator(system,next);
+ plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
+ relocations,RAZOR_STAGE_SCRIPTS_PRE);
+ plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
+ relocations,RAZOR_STAGE_FILES);
+ razor_root_update(root,next);
+ razor_root_commit(root);
+ retval=razor_atomic_commit(atomic);
+ if (!retval)
+ plover_run_transaction(trans,ii,base,install_root,system,next,atomic,
+ relocations,RAZOR_STAGE_SCRIPTS_POST);
+ razor_set_unref(next);
+ razor_install_iterator_destroy(ii);
+ return retval;
+}
+
static int plover_mark_package_for_update(struct razor_transaction *trans,
struct razor_set *set,const char *pkg)
{
int plover_install(const char *base,const char *prefix,char **pkgs)
{
- int i;
+ int i,retval;
char *s;
char *install_root;
struct razor_root *root;
- struct razor_set *system,*set,*upstream,*next;
+ struct razor_set *system,*set,*upstream;
struct razor_transaction *trans;
struct razor_relocations *relocations;
+ struct razor_atomic *atomic;
install_root=getenv("RAZOR_ROOT");
if (!install_root)
install_root="";
relocations=razor_relocations_create();
razor_relocations_add(relocations,"/usr",prefix);
}
+ else
+ relocations=NULL;
+ atomic=razor_atomic_open("Install packages");
/*
* Calling razor_root_open() on a system that hasn't yet had
* razor_root_create() run generates a confusing error message
* on stderr. Avoid this by trying to open it R/O first which
* fails without generating any error.
*/
- set=razor_root_open_read_only(install_root);
+ set=razor_root_open_read_only(install_root,atomic);
if (set)
- razor_set_destroy(set);
+ razor_set_unref(set);
else
razor_root_create(install_root);
- root=razor_root_open(install_root);
+ root=razor_root_open(install_root,atomic);
if (!root)
+ {
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
+ }
system=razor_root_get_system_set(root);
if (!system)
{
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
}
s=plover_strconcat(base,"/repodata",NULL);
- if (!s)
+ if (s)
{
- razor_root_close(root);
- return -1;
+ retval=chdir(s);
+ if (retval<0)
+ perror(s);
}
- if (chdir(s)<0)
+ else
+ retval=-1;
+ free(s);
+ if (retval<0)
{
- perror(s);
- free(s);
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
}
- free(s);
set=plover_razor_set_create_from_yum(base);
- if (!set)
+ if (set)
+ {
+ upstream=plover_relocate_packages(set,atomic,base,relocations);
+ razor_set_unref(set);
+ }
+ else
+ upstream=NULL;
+ if (!upstream)
{
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
}
- upstream=plover_relocate_packages(set,base,relocations);
- razor_set_destroy(set);
trans=razor_transaction_create(system,upstream);
+ razor_set_unref(upstream);
for(i=0;pkgs[i];i++)
if (plover_mark_package_for_update(trans,system,pkgs[i]) &&
plover_mark_package_for_update(trans,upstream,pkgs[i]))
{
fprintf(stderr,"%s: Package not found\n",pkgs[i]);
- razor_root_close(root);
- return -1;
+ retval=-1;
+ break;
}
- razor_transaction_resolve(trans);
- if (razor_transaction_describe(trans)>0)
+ if (!retval)
{
- razor_root_close(root);
- return -1;
+ retval=plover_commit_transaction(trans,base,install_root,root,atomic,
+ relocations);
+ if (retval)
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
}
- next=razor_transaction_commit(trans);
- plover_run_transaction(trans,base,install_root,system,next,relocations);
- razor_root_update(root,next);
+ else
+ razor_root_close(root);
razor_transaction_destroy(trans);
- razor_set_destroy(next);
- razor_set_destroy(upstream);
- if (prefix)
+ razor_atomic_destroy(atomic);
+ if (relocations)
razor_relocations_destroy(relocations);
- return razor_root_commit(root);
+ return retval;
}
int plover_update(const char *base,const char *prefix,char **pkgs)
{
- int i;
+ int i,retval;
char *install_root,*s;
struct razor_root *root;
- struct razor_set *system,*set,*upstream,*next;
+ struct razor_set *system,*set,*upstream;
struct razor_transaction *trans;
struct razor_relocations *relocations;
+ struct razor_atomic *atomic;
install_root=getenv("RAZOR_ROOT");
if (!install_root)
install_root="";
relocations=razor_relocations_create();
razor_relocations_add(relocations,"/usr",prefix);
}
- set=razor_root_open_read_only(install_root);
+ else
+ relocations=NULL;
+ atomic=razor_atomic_open("Update packages");
+ set=razor_root_open_read_only(install_root,atomic);
if (!set)
+ {
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return 0;
- razor_set_destroy(set);
- root=razor_root_open(install_root);
+ }
+ razor_set_unref(set);
+ root=razor_root_open(install_root,atomic);
if (!root)
+ {
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
+ }
system=razor_root_get_system_set(root);
if (!system)
{
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
}
s=plover_strconcat(base,"/repodata",NULL);
- if (!s)
+ if (s)
{
- razor_root_close(root);
- return -1;
+ retval=chdir(s);
+ if (retval)
+ perror(s);
}
- if (chdir(s)<0)
+ else
+ retval=-1;
+ free(s);
+ if (retval)
{
- perror(s);
- free(s);
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
}
- free(s);
set=plover_razor_set_create_from_yum(base);
- if (!set)
+ if (set)
+ {
+ upstream=plover_relocate_packages(set,atomic,base,relocations);
+ razor_set_unref(set);
+ }
+ else
+ upstream=NULL;
+ if (!upstream)
{
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
+ if (relocations)
+ razor_relocations_destroy(relocations);
return -1;
}
- upstream=plover_relocate_packages(set,base,relocations);
- razor_set_destroy(set);
trans=razor_transaction_create(system,upstream);
+ razor_set_unref(upstream);
if (pkgs)
for(i=0;pkgs[i];i++)
{
if (plover_mark_package_for_update(trans,system,pkgs[i]))
{
fprintf(stderr,"%s: Package not found\n",pkgs[i]);
- razor_transaction_destroy(trans);
- razor_set_destroy(upstream);
- razor_set_destroy(system);
- razor_root_close(root);
- return -1;
+ retval=-1;
+ break;
}
}
else
razor_transaction_update_all(trans);
- razor_transaction_resolve(trans);
- if (razor_transaction_describe(trans)>0)
- {
- razor_transaction_destroy(trans);
- razor_set_destroy(upstream);
- razor_set_destroy(system);
- razor_root_close(root);
- return -1;
+ if (!retval) {
+ retval=plover_commit_transaction(trans,base,install_root,root,atomic,
+ relocations);
+ if (retval)
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
}
- next=razor_transaction_commit(trans);
- plover_run_transaction(trans,base,install_root,system,next,relocations);
- razor_root_update(root,next);
+ else
+ razor_root_close(root);
razor_transaction_destroy(trans);
- razor_set_destroy(next);
- razor_set_destroy(upstream);
- return razor_root_commit(root);
+ if (relocations)
+ razor_relocations_destroy(relocations);
+ razor_atomic_destroy(atomic);
+ return retval;
}
static int plover_mark_packages_for_removal(struct razor_transaction *trans,
int plover_remove(char **pkgs)
{
- int i;
+ int i,retval=0;
char *install_root;
struct razor_root *root;
- struct razor_set *system,*set,*upstream,*next;
+ struct razor_set *system,*set,*upstream;
struct razor_transaction *trans;
+ struct razor_atomic *atomic;
install_root=getenv("RAZOR_ROOT");
if (!install_root)
install_root="";
- set=razor_root_open_read_only(install_root);
+ atomic=razor_atomic_open("Remove packages");
+ set=razor_root_open_read_only(install_root,atomic);
if (!set)
+ {
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
+ razor_atomic_destroy(atomic);
return 0;
- razor_set_destroy(set);
- root=razor_root_open(install_root);
+ }
+ razor_set_unref(set);
+ root=razor_root_open(install_root,atomic);
if (!root)
+ {
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
+ razor_atomic_destroy(atomic);
return -1;
+ }
system=razor_root_get_system_set(root);
if (!system)
{
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
razor_root_close(root);
+ razor_atomic_destroy(atomic);
return -1;
}
upstream=razor_set_create_without_root();
trans=razor_transaction_create(system,upstream);
+ razor_set_unref(upstream);
if (pkgs)
for(i=0;pkgs[i];i++)
{
if (plover_mark_packages_for_removal(trans,system,pkgs[i]))
{
fprintf(stderr,"%s: Package not found\n",pkgs[i]);
- razor_transaction_destroy(trans);
- razor_set_destroy(upstream);
- razor_set_destroy(system);
- razor_root_close(root);
- return -1;
+ retval=-1;
+ break;
}
}
else
plover_mark_packages_for_removal(trans,system,NULL);
- razor_transaction_resolve(trans);
- if (razor_transaction_describe(trans)>0)
+ if (!retval)
{
- razor_transaction_destroy(trans);
- razor_set_destroy(upstream);
- razor_set_destroy(system);
- razor_root_close(root);
- return -1;
+ retval=
+ plover_commit_transaction(trans,NULL,install_root,root,atomic,NULL);
+ if (retval)
+ fprintf(stderr,"%s\n",razor_atomic_get_error_msg(atomic));
}
- next=razor_transaction_commit(trans);
- plover_run_transaction(trans,NULL,install_root,system,next,NULL);
- razor_root_update(root,next);
+ else
+ razor_root_close(root);
razor_transaction_destroy(trans);
- razor_set_destroy(next);
- razor_set_destroy(upstream);
- return razor_root_commit(root);
+ razor_atomic_destroy(atomic);
+ return retval;
+}
+
+/*
+ * Note: If there are no installed files, then any prefix will match.
+ */
+
+int plover_installed_files_match_prefix(const char *prefix)
+{
+ int len,matches=1;
+ const char *name;
+ char *install_root;
+ struct razor_set *set;
+ struct razor_atomic *atomic;
+ struct razor_package *package;
+ struct razor_package_iterator *pi;
+ struct razor_file_iterator *fi;
+ len=strlen(prefix);
+ while(len && prefix[len-1]=='/')
+ len--;
+ install_root=getenv("RAZOR_ROOT");
+ if (!install_root)
+ install_root="";
+ atomic=razor_atomic_open("Query packages");
+ set=razor_root_open_read_only(install_root,atomic);
+ if (set)
+ {
+ pi=razor_package_iterator_create(set);
+ while (matches &&
+ razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
+ {
+ fi=razor_file_iterator_create(set,package,0);
+ while (matches && razor_file_iterator_next(fi,&name))
+ {
+ if (strncmp(name,prefix,len) ||
+ name[len]!='\0' && name[len]!='/')
+ matches=0;
+ }
+ razor_file_iterator_destroy(fi);
+ }
+ razor_package_iterator_destroy(pi);
+ razor_set_unref(set);
+ }
+ razor_atomic_destroy(atomic);
+ return matches;
}