plover-gtk/packageset.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Nov 10 11:00:49 2011 +0000 (2011-11-10)
changeset 12 1d18b9c34d26
parent 9 8d3b1ddf789c
child 13 b0a35bae4961
permissions -rw-r--r--
Fix warnings
     1 /*
     2  * Copyright (C) 2010  J. Ali Harlow <ali@juiblex.co.uk>
     3  *
     4  * This program is free software; you can redistribute it and/or modify
     5  * it under the terms of the GNU General Public License as published by
     6  * the Free Software Foundation; either version 2 of the License, or
     7  * (at your option) any later version.
     8  *
     9  * This program is distributed in the hope that it will be useful,
    10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  * GNU General Public License for more details.
    13  *
    14  * You should have received a copy of the GNU General Public License along
    15  * with this program; if not, write to the Free Software Foundation, Inc.,
    16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    17  */
    18 
    19 #include "config.h"
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #include <fcntl.h>
    23 #include <errno.h>
    24 #include <glib-object.h>
    25 #include <razor.h>
    26 #include "plover/plover.h"
    27 #include "plover-gtk/error.h"
    28 #include "plover-gtk/packageset.h"
    29 #include "plover-gtk/package.h"
    30 
    31 G_DEFINE_TYPE(PloverPackageSet,plover_package_set,G_TYPE_OBJECT);
    32 
    33 typedef struct _PloverPackageSetPrivate {
    34     struct razor_root *root;
    35     struct razor_set *set;
    36     GSList *packages;
    37     int no_details;
    38 } PloverPackageSetPrivate;
    39 
    40 #define PLOVER_PACKAGE_SET_GET_PRIVATE(obj)\
    41 				G_TYPE_INSTANCE_GET_PRIVATE(obj,\
    42 				  PLOVER_TYPE_PACKAGE_SET,\
    43 				  PloverPackageSetPrivate)
    44 
    45 enum {
    46     CHANGED=0,
    47     N_SIGNALS
    48 };
    49 
    50 static guint signals[N_SIGNALS];
    51 
    52 static void plover_package_set_finalize(GObject *obj)
    53 {
    54     PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
    55     if (priv->root)
    56     {
    57 	/* priv->set, if set, is owned by priv->root and should not
    58 	 * be destroyed.
    59 	 */
    60 	razor_root_close(priv->root);
    61     }
    62     else if (priv->set)
    63 	razor_set_destroy(priv->set);
    64     if (G_OBJECT_CLASS(plover_package_set_parent_class)->finalize)
    65 	G_OBJECT_CLASS(plover_package_set_parent_class)->finalize(obj);
    66 }
    67 
    68 static void plover_package_set_dispose(GObject *obj)
    69 {
    70     PloverPackageSetPrivate *priv=PLOVER_PACKAGE_SET_GET_PRIVATE(obj);
    71     if (G_OBJECT_CLASS(plover_package_set_parent_class)->dispose)
    72 	G_OBJECT_CLASS(plover_package_set_parent_class)->dispose(obj);
    73 }
    74 
    75 static void plover_package_set_class_init(PloverPackageSetClass *klass)
    76 {
    77     GObjectClass *oclass=G_OBJECT_CLASS(klass);
    78     oclass->finalize=plover_package_set_finalize;
    79     oclass->dispose=plover_package_set_dispose;
    80     g_type_class_add_private(klass,sizeof(PloverPackageSetPrivate));
    81     signals[CHANGED]=g_signal_newv("changed",
    82       G_TYPE_FROM_CLASS(klass),G_SIGNAL_RUN_LAST,NULL,NULL,NULL,
    83       g_cclosure_marshal_VOID__VOID,G_TYPE_NONE,0,NULL);
    84 }
    85 
    86 static void plover_package_set_init(PloverPackageSet *set)
    87 {
    88     PloverPackageSetPrivate *priv;
    89     priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
    90     priv->no_details=-1;
    91 }
    92 
    93 PloverPackageSet *plover_package_set_new(void)
    94 {
    95     return g_object_new(PLOVER_TYPE_PACKAGE_SET,NULL);
    96 }
    97 
    98 PloverPackageSet *plover_package_set_new_from_installed(const char *root,
    99   GError **err)
   100 {
   101     PloverPackageSet *set;
   102     PloverPackageSetPrivate *priv;
   103     set=plover_package_set_new();
   104     priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
   105     priv->root=razor_root_open(root);
   106     if (!priv->root)
   107     {
   108 	g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
   109 	  "Failed to open %s as razor root",root);
   110 	g_object_unref(set);
   111 	return NULL;
   112     }
   113     priv->set=razor_root_get_system_set(priv->root);
   114     if (!priv->set)
   115     {
   116 	g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
   117 	  "Failed to get system set from %s",root);
   118 	g_object_unref(set);
   119 	return NULL;
   120     }
   121     return set;
   122 }
   123 
   124 PloverPackageSet *plover_package_set_new_from_repository(const char *base,
   125   struct razor_relocations *relocations,GError **err)
   126 {
   127 #if HAVE_FCHDIR
   128     int fd;
   129 #else
   130     size_t wd_len;
   131     char *wd;
   132 #endif
   133     gchar *s;
   134     struct razor_set *reloc;
   135     PloverPackageSet *set;
   136     PloverPackageSetPrivate *priv;
   137     set=plover_package_set_new();
   138     priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
   139 #if HAVE_FCHDIR
   140     fd=open(".",O_RDONLY);
   141 #else
   142     wd_len=32;
   143     wd=malloc(wd_len);
   144     while (!getcwd(wd,wd_len) && errno==ERANGE)
   145     {
   146 	free(wd);
   147 	wd_len*=2;
   148 	wd=malloc(wd_len);
   149     }
   150 #endif
   151     s=g_build_filename(base,"repodata",NULL);
   152     if (chdir(s)<0)
   153     {
   154 	g_set_error(err,G_FILE_ERROR,g_file_error_from_errno(errno),
   155 	  "%s: %s",s,g_strerror(errno));
   156 	g_object_unref(set);
   157 #if HAVE_FCHDIR
   158 	close(fd);
   159 #else
   160 	free(wd);
   161 #endif
   162 	return NULL;
   163     }
   164     g_free(s);
   165     priv->set=plover_razor_set_create_from_yum("..");
   166 #if HAVE_FCHDIR
   167     fchdir(fd);
   168     close(fd);
   169 #else
   170     chdir(wd);
   171     free(wd);
   172 #endif
   173     if (priv->set && relocations)
   174     {
   175 	reloc=plover_relocate_packages(priv->set,base,relocations);
   176 	razor_set_destroy(priv->set);
   177 	priv->set=reloc;
   178     }
   179     if (!priv->set)
   180     {
   181 	g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
   182 	  "Failed to create package set from repository %s",base);
   183 	g_object_unref(set);
   184 	return NULL;
   185     }
   186     return set;
   187 }
   188 
   189 GSList *plover_package_set_get_packages(PloverPackageSet *set)
   190 {
   191     struct razor_package_iterator *iter;
   192     struct razor_package *pkg;
   193     PloverPackageSetPrivate *priv;
   194     PloverPackage *package;
   195     g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),NULL);
   196     priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
   197     if (priv->set && !priv->packages)
   198     {
   199 	iter=razor_package_iterator_create(priv->set);
   200 	while(razor_package_iterator_next(iter,&pkg,RAZOR_DETAIL_LAST))
   201 	{
   202 	    package=plover_package_new(priv->set,pkg);
   203 	    priv->packages=g_slist_prepend(priv->packages,package);
   204 	}
   205 	razor_package_iterator_destroy(iter);
   206     }
   207     return priv->packages;
   208 }
   209 
   210 /*
   211  * Some versions of razor have a bug which causes all detail strings
   212  * to be discarded. If such a version of razor is used to install or
   213  * update a package, then all the detail strings for the installed
   214  * set will be lost. This function tests for this condition and can
   215  * be used to present something more useful than blank details.
   216  */
   217 
   218 gboolean plover_package_set_get_no_details(PloverPackageSet *set)
   219 {
   220     PloverPackageSetPrivate *priv;
   221     PloverPackage *package;
   222     GSList *packages,*link;
   223     g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
   224     priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
   225     if (priv->no_details<0)
   226     {
   227 	packages=plover_package_set_get_packages(set);
   228 	if (packages)
   229 	{
   230 	    priv->no_details=0;
   231 	    for(link=packages;link;link=link->next)
   232 	    {
   233 		package=link->data;
   234 		priv->no_details+=2;
   235 		if (*plover_package_get_summary(package))
   236 		    priv->no_details--;
   237 		if (*plover_package_get_license(package))
   238 		    priv->no_details--;
   239 		if (*plover_package_get_description(package))
   240 		    priv->no_details--;
   241 		if (*plover_package_get_URL(package))
   242 		    priv->no_details--;
   243 	    }
   244 	    if (priv->no_details<0)	/* More than 50% of strings present */
   245 		priv->no_details=0;
   246 	}
   247     }
   248     return priv->no_details>0;
   249 }