plover/razor.c
author J. Ali Harlow <ali@juiblex.co.uk>
Wed Jun 22 17:04:28 2016 +0100 (2016-06-22)
changeset 44 43ffed8669ce
parent 43 6b3034a884dc
child 47 2d0ee44ab3c6
permissions -rw-r--r--
Port to razor 0.6.3.60
ali@0
     1
/*
ali@0
     2
 * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
ali@0
     3
 * Copyright (C) 2008  Red Hat, Inc
ali@24
     4
 * Copyright (C) 2009, 2011, 2012, 2014  J. Ali Harlow <ali@juiblex.co.uk>
ali@0
     5
 *
ali@0
     6
 * This program is free software; you can redistribute it and/or modify
ali@0
     7
 * it under the terms of the GNU General Public License as published by
ali@0
     8
 * the Free Software Foundation; either version 2 of the License, or
ali@0
     9
 * (at your option) any later version.
ali@0
    10
 *
ali@0
    11
 * This program is distributed in the hope that it will be useful,
ali@0
    12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@0
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@0
    14
 * GNU General Public License for more details.
ali@0
    15
 *
ali@0
    16
 * You should have received a copy of the GNU General Public License along
ali@0
    17
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@0
    18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@0
    19
 */
ali@0
    20
ali@0
    21
#include <stdlib.h>
ali@0
    22
#include <stdio.h>
ali@0
    23
#include <stdarg.h>
ali@0
    24
#include <string.h>
ali@24
    25
#include <errno.h>
ali@0
    26
#include <unistd.h>
ali@0
    27
#include <razor.h>
ali@24
    28
#include <glib.h>
ali@24
    29
#include <gio/gio.h>
ali@0
    30
#include "config.h"
ali@0
    31
#include "plover/plover.h"
ali@24
    32
#include "plover/transaction.h"
ali@44
    33
#include "plover/uri-handler.h"
ali@0
    34
ali@0
    35
static char *rpm_filename(const char *name,const char *version,const char *arch)
ali@0
    36
{
ali@0
    37
    const char *v;
ali@0
    38
    v=strchr(version,':');	      /* Skip epoch */
ali@0
    39
    if (v)
ali@0
    40
	v++;
ali@0
    41
    else
ali@0
    42
	v=version;
ali@24
    43
    return g_strconcat(name,"-",v,".",arch,".rpm",NULL);
ali@0
    44
}
ali@0
    45
ali@19
    46
/*
ali@19
    47
 * Returns 0 on success, -1 on failure and 1 if a RAZOR_INSTALL_ACTION_COMMIT
ali@19
    48
 * is met (in which case the action is consumed).
ali@19
    49
 */
ali@13
    50
int plover_run_transaction(struct razor_transaction *trans,
ali@24
    51
  struct razor_install_iterator *ii,const char *install_root,
ali@24
    52
  struct razor_set *system,PloverPackageSet *next,PloverRepository *upstream,
ali@24
    53
  struct razor_atomic *atomic,struct razor_relocations *relocations,
ali@24
    54
  enum razor_stage_type stage,GCancellable *cancellable)
ali@0
    55
{
ali@24
    56
    struct razor_package *pkg;
ali@0
    57
    enum razor_install_action action;
ali@0
    58
    struct razor_rpm *rpm;
ali@19
    59
    struct razor_error *error=NULL;
ali@0
    60
    const char *name,*version,*arch;
ali@24
    61
    gchar *t;
ali@19
    62
    int r,count;
ali@24
    63
    GError *tmp_error=NULL;
ali@24
    64
    PloverPackage *package;
ali@42
    65
    GFile *file;
ali@42
    66
    gchar *uri;
ali@44
    67
    plover__uri_handler_init();
ali@42
    68
    file=g_file_new_for_path(*install_root?install_root:"/");
ali@42
    69
    uri=g_file_get_uri(file);
ali@42
    70
    g_object_unref(file);
ali@42
    71
    g_message("Using %s as URI",uri);
ali@13
    72
    switch(stage)
ali@13
    73
    {
ali@13
    74
	case RAZOR_STAGE_SCRIPTS_PRE:
ali@13
    75
	    printf("Running pre-transaction scripts\n");
ali@13
    76
	    break;
ali@13
    77
	case RAZOR_STAGE_FILES:
ali@13
    78
	    printf("Running Transaction\n");
ali@13
    79
	    break;
ali@13
    80
	case RAZOR_STAGE_SCRIPTS_POST:
ali@13
    81
	    printf("Running post-transaction scripts\n");
ali@13
    82
	    break;
ali@13
    83
	default:
ali@13
    84
	    /* Keep the compiler happy */
ali@13
    85
	    break;
ali@13
    86
    }
ali@24
    87
    while (razor_install_iterator_next(ii,&pkg,&action,&count))
ali@0
    88
    {
ali@24
    89
	if (g_cancellable_is_cancelled(cancellable))
ali@24
    90
	{
ali@24
    91
	    razor_atomic_abort(atomic,PLOVER_GENERAL_ERROR,
ali@24
    92
	      PLOVER_GENERAL_ERROR_CANCELLED,"Operation was cancelled");
ali@42
    93
	    g_free(uri);
ali@24
    94
	    return -1;
ali@24
    95
	}
ali@0
    96
	if (action==RAZOR_INSTALL_ACTION_REMOVE)
ali@0
    97
	{
ali@24
    98
	    razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
ali@0
    99
	      RAZOR_DETAIL_LAST);
ali@13
   100
	    if (stage==RAZOR_STAGE_FILES)
ali@13
   101
		printf("  Removing : %s ",name);
ali@24
   102
	    r=razor_package_remove(system,plover_package_set_get_razor(next),
ali@42
   103
	      atomic,pkg,uri,count,stage);
ali@13
   104
	    if (stage==RAZOR_STAGE_FILES)
ali@13
   105
		printf("\n");
ali@0
   106
	}
ali@19
   107
	else if (action==RAZOR_INSTALL_ACTION_ADD)
ali@0
   108
	{
ali@24
   109
	    package=plover_package_set_lookup(next,pkg);
ali@24
   110
	    rpm=plover_repository_open_rpm(upstream,package,&tmp_error);
ali@0
   111
	    if (!rpm)
ali@19
   112
	    {
ali@24
   113
		plover_propagate_g_error(&error,tmp_error);
ali@24
   114
		razor_atomic_propagate_error(atomic,error,NULL);
ali@19
   115
		razor_error_free(error);
ali@42
   116
		g_free(uri);
ali@0
   117
		return -1;
ali@19
   118
	    }
ali@13
   119
	    if (stage==RAZOR_STAGE_FILES)
ali@24
   120
		printf("  Installing : %s ",plover_package_get_name(package));
ali@0
   121
	    if (relocations)
ali@0
   122
		razor_rpm_set_relocations(rpm,relocations);
ali@24
   123
	    razor_transaction_fixup_package(trans,pkg,rpm);
ali@42
   124
	    r=razor_rpm_install(rpm,atomic,uri,1,stage);
ali@0
   125
	    razor_rpm_close(rpm);
ali@13
   126
	    if (stage==RAZOR_STAGE_FILES)
ali@13
   127
		printf("\n");
ali@0
   128
	}
ali@19
   129
	else if (action==RAZOR_INSTALL_ACTION_COMMIT)
ali@19
   130
	    return 1;
ali@19
   131
	else
ali@19
   132
	    r=0;
ali@13
   133
	if (razor_atomic_in_error_state(atomic))
ali@42
   134
	{
ali@42
   135
	    g_free(uri);
ali@13
   136
	    return -1;
ali@42
   137
	}
ali@19
   138
	else if (r)
ali@19
   139
	{
ali@29
   140
	    if (action==RAZOR_INSTALL_ACTION_REMOVE)
ali@29
   141
	    {
ali@29
   142
		razor_package_get_details(system,pkg,RAZOR_DETAIL_NAME,&name,
ali@29
   143
		  RAZOR_DETAIL_VERSION,&version,RAZOR_DETAIL_ARCH,&arch,
ali@29
   144
		  RAZOR_DETAIL_LAST);
ali@29
   145
	    }
ali@29
   146
	    else
ali@29
   147
	    {
ali@29
   148
		package=plover_package_set_lookup(next,pkg);
ali@29
   149
		name=plover_package_get_name(package);
ali@29
   150
		version=plover_package_get_version(package);
ali@29
   151
		arch=plover_package_get_arch(package);
ali@29
   152
	    }
ali@19
   153
	    /*
ali@19
   154
	     * If a pre or preun script fails, then we should
ali@19
   155
	     * treat that as a fatal error. post and postun
ali@19
   156
	     * script failures are treated as warnings. Be
ali@19
   157
	     * nice and tell the user _which_ script failed.
ali@19
   158
	     */
ali@19
   159
	    if (stage==RAZOR_STAGE_SCRIPTS_PRE)
ali@22
   160
	    {
ali@24
   161
		t=g_strconcat(action==RAZOR_INSTALL_ACTION_ADD?
ali@24
   162
		  "%pre":"%preun","(",name,"-",version,".",arch,
ali@24
   163
		  ") scriptlet failed",NULL);
ali@24
   164
		fprintf(stderr,"error: %s, exit status %d\n",t,r);
ali@24
   165
		razor_atomic_abort(atomic,PLOVER_SCRIPTLET_ERROR,r,t);
ali@24
   166
		g_free(t);
ali@42
   167
		g_free(uri);
ali@19
   168
		return -1;
ali@22
   169
	    }
ali@22
   170
	    else
ali@22
   171
		fprintf(stderr,
ali@22
   172
		  "warning: %s(%s-%s.%s) scriptlet failed, exit status %d\n",
ali@22
   173
		  action==RAZOR_INSTALL_ACTION_ADD?"%post":"%postun",
ali@22
   174
		  name,version,arch,r);
ali@19
   175
	}
ali@0
   176
    }
ali@42
   177
    g_free(uri);
ali@13
   178
    return 0;
ali@13
   179
}
ali@13
   180
ali@43
   181
gboolean plover_install_uri(const char *base_uri,const char *prefix,char **pkgs,
ali@43
   182
  GError **error)
ali@43
   183
{
ali@43
   184
    gboolean retval;
ali@43
   185
    PloverTransaction *transaction;
ali@43
   186
    transaction=plover_transaction_new_install_uri(base_uri,prefix,pkgs,error);
ali@43
   187
    if (!transaction)
ali@43
   188
	return FALSE;
ali@43
   189
    retval=plover_transaction_commit(transaction,NULL,error);
ali@43
   190
    g_object_unref(transaction);
ali@43
   191
    return retval;
ali@43
   192
}
ali@43
   193
ali@24
   194
gboolean plover_install(const char *base,const char *prefix,char **pkgs,
ali@24
   195
  GError **error)
ali@13
   196
{
ali@24
   197
    gboolean retval;
ali@43
   198
    GFile *file;
ali@43
   199
    gchar *base_uri;
ali@43
   200
    file=g_file_new_for_path(base);
ali@43
   201
    base_uri=g_file_get_uri(file);
ali@43
   202
    g_object_unref(file);
ali@43
   203
    retval=plover_install_uri(base_uri,prefix,pkgs,error);
ali@43
   204
    g_free(base_uri);
ali@13
   205
    return retval;
ali@0
   206
}
ali@0
   207
ali@24
   208
gboolean plover_update(const char *base,const char *prefix,char **pkgs,
ali@24
   209
  GError **error)
ali@0
   210
{
ali@24
   211
    gboolean retval;
ali@24
   212
    GError *tmp_error=NULL;
ali@24
   213
    PloverTransaction *transaction;
ali@24
   214
    transaction=plover_transaction_new_update(base,prefix,pkgs,&tmp_error);
ali@24
   215
    if (!transaction)
ali@0
   216
    {
ali@24
   217
	retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT);
ali@24
   218
	if (retval)
ali@24
   219
	    g_error_free(tmp_error);
ali@24
   220
	else
ali@24
   221
	    g_propagate_error(error,tmp_error);
ali@0
   222
    }
ali@24
   223
    else
ali@24
   224
    {
ali@24
   225
	retval=plover_transaction_commit(transaction,NULL,error);
ali@24
   226
	g_object_unref(transaction);
ali@24
   227
    }
ali@0
   228
    return retval;
ali@0
   229
}
ali@0
   230
ali@24
   231
gboolean plover_remove(char **pkgs,GError **error)
ali@0
   232
{
ali@24
   233
    gboolean retval;
ali@24
   234
    GError *tmp_error=NULL;
ali@24
   235
    PloverTransaction *transaction;
ali@24
   236
    transaction=plover_transaction_new_remove(pkgs,&tmp_error);
ali@24
   237
    if (!transaction)
ali@0
   238
    {
ali@24
   239
	retval=g_error_matches(tmp_error,PLOVER_POSIX_ERROR,ENOENT);
ali@24
   240
	if (retval)
ali@24
   241
	{
ali@24
   242
	    g_error_free(tmp_error);
ali@24
   243
	    if (pkgs)
ali@24
   244
	    {
ali@24
   245
		g_set_error(error,PLOVER_GENERAL_ERROR,
ali@24
   246
		  PLOVER_GENERAL_ERROR_NO_SUCH_PACKAGE,"%s: %s",pkgs[0],
ali@24
   247
		  "Package not found");
ali@24
   248
		retval=FALSE;
ali@24
   249
	    }
ali@24
   250
	}
ali@19
   251
	else
ali@24
   252
	    g_propagate_error(error,tmp_error);
ali@13
   253
    }
ali@13
   254
    else
ali@19
   255
    {
ali@24
   256
	retval=plover_transaction_commit(transaction,NULL,error);
ali@24
   257
	g_object_unref(transaction);
ali@19
   258
    }
ali@13
   259
    return retval;
ali@13
   260
}
ali@13
   261
ali@13
   262
/*
ali@13
   263
 * Note: If there are no installed files, then any prefix will match.
ali@13
   264
 */
ali@13
   265
ali@13
   266
int plover_installed_files_match_prefix(const char *prefix)
ali@13
   267
{
ali@13
   268
    int len,matches=1;
ali@13
   269
    const char *name;
ali@42
   270
    const char *install_root;
ali@13
   271
    struct razor_set *set;
ali@13
   272
    struct razor_package *package;
ali@13
   273
    struct razor_package_iterator *pi;
ali@13
   274
    struct razor_file_iterator *fi;
ali@44
   275
    plover__uri_handler_init();
ali@13
   276
    len=strlen(prefix);
ali@13
   277
    while(len && prefix[len-1]=='/')
ali@13
   278
	len--;
ali@42
   279
    install_root=g_getenv("RAZOR_ROOT");
ali@13
   280
    if (!install_root)
ali@42
   281
	install_root="file:///";
ali@42
   282
    set=razor_root_open_read_only(install_root,NULL);
ali@42
   283
    if (!set)
ali@42
   284
	g_message("Failed to open root");
ali@13
   285
    if (set)
ali@13
   286
    {
ali@13
   287
	pi=razor_package_iterator_create(set);
ali@13
   288
	while (matches &&
ali@13
   289
	  razor_package_iterator_next(pi,&package,RAZOR_DETAIL_LAST))
ali@13
   290
	{
ali@13
   291
	    fi=razor_file_iterator_create(set,package,0);
ali@13
   292
	    while (matches && razor_file_iterator_next(fi,&name))
ali@13
   293
	    {
ali@13
   294
		if (strncmp(name,prefix,len) ||
ali@13
   295
		  name[len]!='\0' && name[len]!='/')
ali@13
   296
		    matches=0;
ali@13
   297
	    }
ali@13
   298
	    razor_file_iterator_destroy(fi);
ali@13
   299
	}
ali@13
   300
	razor_package_iterator_destroy(pi);
ali@13
   301
	razor_set_unref(set);
ali@0
   302
    }
ali@13
   303
    return matches;
ali@0
   304
}