/* * Copyright (C) 2010 J. Ali Harlow * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #include #include "plover/plover.h" #include "plover-gtk/error.h" #include "plover-gtk/packageset.h" #include "plover-gtk/package.h" G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT); typedef struct _PloverPackageSetPrivate { struct razor_root *root; struct razor_set *set; GSList *packages; int no_details; } PloverPackageSetPrivate; #define PLOVER_PACKAGE_SET_GET_PRIVATE(obj)\ G_TYPE_INSTANCE_GET_PRIVATE(obj,\ PLOVER_TYPE_PACKAGE_SET,\ PloverPackageSetPrivate) enum { CHANGED=0, N_SIGNALS }; static guint signals[N_SIGNALS]; static void plover_package_set_finalize(GObject *obj) { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); if (priv->root) { /* priv->set, if set, is owned by priv->root and should not * be destroyed. */ razor_root_close(priv->root); } else if (priv->set) razor_set_destroy(priv->set); if (G_OBJECT_CLASS(plover_package_set_parent_class)->finalize) G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj); } static void plover_package_set_dispose(GObject *obj) { PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj); if (G_OBJECT_CLASS(plover_package_set_parent_class)->dispose) G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj); } static void plover_package_set_class_init(PloverPackageSetClass *klass) { GObjectClass *oclass=G_OBJECT_CLASS(klass); oclass->finalize=plover_package_set_finalize; oclass->dispose=plover_package_set_dispose; g_type_class_add_private(klass,sizeof(PloverPackageSetPrivate)); signals[CHANGED]=g_signal_newv("changed", G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL, g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL); } static void plover_package_set_init(PloverPackageSet *set) { PloverPackageSetPrivate *priv; priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); priv->no_details=-1; } PloverPackageSet *plover_package_set_new(void) { return g_object_new(PLOVER_TYPE_PACKAGE_SET,NULL); } PloverPackageSet *plover_package_set_new_from_installed(const char *root, GError **err) { PloverPackageSet *set; PloverPackageSetPrivate *priv; set=plover_package_set_new(); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); priv->root=razor_root_open(root); if (!priv->root) { g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED, "Failed to open %s as razor root",root); g_object_unref(set); return NULL; } priv->set=razor_root_get_system_set(priv->root); if (!priv->set) { g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED, "Failed to get system set from %s",root); g_object_unref(set); return NULL; } return set; } PloverPackageSet *plover_package_set_new_from_repository(const char *base, struct razor_relocations *relocations,GError **err) { #if HAVE_FCHDIR int fd; #else size_t wd_len; char *wd; #endif gchar *s; struct razor_set *reloc; PloverPackageSet *set; PloverPackageSetPrivate *priv; set=plover_package_set_new(); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); #if HAVE_FCHDIR fd=open(".",O_RDONLY); #else wd_len=32; wd=malloc(wd_len); while (!getcwd(wd,wd_len) && errno==ERANGE) { free(wd); wd_len*=2; wd=malloc(wd_len); } #endif s=g_build_filename(base,"repodata",NULL); if (chdir(s)<0) { g_set_error(err,G_FILE_ERROR,g_file_error_from_errno(errno), "%s: %s",s,g_strerror(errno)); g_object_unref(set); #if HAVE_FCHDIR close(fd); #else free(wd); #endif return NULL; } g_free(s); priv->set=plover_razor_set_create_from_yum(".."); #if HAVE_FCHDIR fchdir(fd); close(fd); #else chdir(wd); free(wd); #endif if (priv->set && relocations) { reloc=plover_relocate_packages(priv->set,base,relocations); razor_set_destroy(priv->set); priv->set=reloc; } if (!priv->set) { g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED, "Failed to create package set from repository %s",base); g_object_unref(set); return NULL; } return set; } GSList *plover_package_set_get_packages(PloverPackageSet *set) { struct razor_package_iterator *iter; struct razor_package *pkg; PloverPackageSetPrivate *priv; PloverPackage *package; g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); if (priv->set && !priv->packages) { iter=razor_package_iterator_create(priv->set); while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_LAST)) { package=plover_package_new(priv->set,pkg); priv->packages=g_slist_prepend(priv->packages,package); } razor_package_iterator_destroy(iter); } return priv->packages; } /* * Some versions of razor have a bug which causes all detail strings * to be discarded. If such a version of razor is used to install or * update a package, then all the detail strings for the installed * set will be lost. This function tests for this condition and can * be used to present something more useful than blank details. */ gboolean plover_package_set_get_no_details(PloverPackageSet *set) { PloverPackageSetPrivate *priv; PloverPackage *package; GSList *packages,*link; g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE); priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set); if (priv->no_details<0) { packages=plover_package_set_get_packages(set); if (packages) { priv->no_details=0; for(link=packages;link;link=link->next) { package=link->data; priv->no_details+=2; if (*plover_package_get_summary(package)) priv->no_details--; if (*plover_package_get_license(package)) priv->no_details--; if (*plover_package_get_description(package)) priv->no_details--; if (*plover_package_get_URL(package)) priv->no_details--; } if (priv->no_details<0) /* More than 50% of strings present */ priv->no_details=0; } } return priv->no_details>0; }