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