gboolean
pk_backend_transaction_simulate (PkBackend *self, GError **error)
{
	alpm_list_t *data = NULL;
	gchar *prefix;

	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (alpm != NULL, FALSE);

	if (alpm_trans_prepare (alpm, &data) >= 0) {
		return TRUE;
	}

	switch (alpm_errno (alpm)) {
		case ALPM_ERR_PKG_INVALID_ARCH:
			prefix = alpm_pkg_build_list (data);
			alpm_list_free (data);
			break;

		case ALPM_ERR_UNSATISFIED_DEPS:
			prefix = alpm_miss_build_list (data);
			alpm_list_free_inner (data, alpm_depmissing_free);
			alpm_list_free (data);
			break;

		case ALPM_ERR_CONFLICTING_DEPS:
			prefix = alpm_conflict_build_list (data);
			alpm_list_free_inner (data, alpm_conflict_free);
			alpm_list_free (data);
			break;

		case ALPM_ERR_FILE_CONFLICTS:
			prefix = alpm_fileconflict_build_list (data);
			alpm_list_free_inner (data, alpm_fileconflict_free);
			alpm_list_free (data);
			break;

		default:
			prefix = NULL;
			if (data != NULL) {
				g_warning ("unhandled error %d",
					   alpm_errno (alpm));
			}
			break;
	}

	if (prefix != NULL) {
		alpm_errno_t errno = alpm_errno (alpm);
		g_set_error (error, ALPM_ERROR, errno, "%s: %s", prefix,
			     alpm_strerror (errno));
		g_free (prefix);
	} else {
		alpm_errno_t errno = alpm_errno (alpm);
		g_set_error_literal (error, ALPM_ERROR, errno,
				     alpm_strerror (errno));
	}

	return FALSE;
}
Esempio n. 2
0
static PyObject* pyalpm_trans_prepare(PyObject *self, PyObject *args) {
  alpm_handle_t *handle = ALPM_HANDLE(self);
  alpm_list_t *data;

  int ret = alpm_trans_prepare(handle, &data);
  if (ret == -1) {
    /* return the list of package conflicts in the exception */
    PyObject *info = alpmlist_to_pylist(data, pyobject_from_pmdepmissing);
    if (!info) return NULL;
    RET_ERR_DATA("transaction preparation failed", alpm_errno(handle), info, NULL);
  }

  Py_RETURN_NONE;
}
Esempio n. 3
0
int lalpm_trans_prepare(lua_State *L)
{
    alpm_list_t *list = NULL;
    const int result = alpm_trans_prepare(&list);
    lua_pushnumber(L, result);
    if (result == -1) {
        switch(pm_errno) {
            case PM_ERR_UNSATISFIED_DEPS:
                alpm_list_to_any_table(L, list, PMDEPMISSING_T);
                break;
            case PM_ERR_CONFLICTING_DEPS:
                alpm_list_to_any_table(L, list, PMCONFLICT_T);
                break;
            case PM_ERR_FILE_CONFLICTS:
                alpm_list_to_any_table(L, list, PMFILECONFLICT_T);
                break;
            default:
                break;
        }
        return 2;
    }

    return 1;
}
Esempio n. 4
0
/**
 * @brief Upgrade a specified list of packages.
 *
 * @param targets a list of packages (as strings) to upgrade
 *
 * @return 0 on success, 1 on failure
 */
int pacman_upgrade(alpm_list_t *targets)
{
	alpm_list_t *i, *data = NULL;
	pgp_verify_t check_sig = alpm_option_get_default_sigverify(config->handle);
	int retval = 0;

	if(targets == NULL) {
		pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
		return 1;
	}

	/* Check for URL targets and process them
	 */
	for(i = targets; i; i = alpm_list_next(i)) {
		if(strstr(i->data, "://")) {
			char *str = alpm_fetch_pkgurl(config->handle, i->data);
			if(str == NULL) {
				pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
						(char *)i->data, alpm_strerror(alpm_errno(config->handle)));
				return 1;
			} else {
				free(i->data);
				i->data = str;
			}
		}
	}

	/* Step 1: create a new transaction */
	if(trans_init(config->flags) == -1) {
		return 1;
	}

	/* add targets to the created transaction */
	for(i = targets; i; i = alpm_list_next(i)) {
		char *targ = alpm_list_getdata(i);
		pmpkg_t *pkg;

		if(alpm_pkg_load(config->handle, targ, 1, check_sig, &pkg) != 0) {
			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
					targ, alpm_strerror(alpm_errno(config->handle)));
			trans_release();
			return 1;
		}
		if(alpm_add_pkg(config->handle, pkg) == -1) {
			pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n",
					targ, alpm_strerror(alpm_errno(config->handle)));
			alpm_pkg_free(pkg);
			trans_release();
			return 1;
		}
	}

	/* Step 2: "compute" the transaction based on targets and flags */
	/* TODO: No, compute nothing. This is stupid. */
	if(alpm_trans_prepare(config->handle, &data) == -1) {
		enum _pmerrno_t err = alpm_errno(config->handle);
		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
		        alpm_strerror(err));
		switch(err) {
			case PM_ERR_PKG_INVALID_ARCH:
				for(i = data; i; i = alpm_list_next(i)) {
					char *pkg = alpm_list_getdata(i);
					printf(_(":: package %s does not have a valid architecture\n"), pkg);
				}
				break;
			case PM_ERR_UNSATISFIED_DEPS:
				for(i = data; i; i = alpm_list_next(i)) {
					pmdepmissing_t *miss = alpm_list_getdata(i);
					char *depstring = alpm_dep_compute_string(miss->depend);

					/* TODO indicate if the error was a virtual package or not:
					 *		:: %s: requires %s, provided by %s
					 */
					printf(_(":: %s: requires %s\n"), miss->target, depstring);
					free(depstring);
				}
				break;
			case PM_ERR_CONFLICTING_DEPS:
				for(i = data; i; i = alpm_list_next(i)) {
					pmconflict_t *conflict = alpm_list_getdata(i);
					if(strcmp(conflict->package1, conflict->reason) == 0 ||
							strcmp(conflict->package2, conflict->reason) == 0) {
						printf(_(":: %s and %s are in conflict\n"),
								conflict->package1, conflict->package2);
					} else {
						printf(_(":: %s and %s are in conflict (%s)\n"),
								conflict->package1, conflict->package2, conflict->reason);
					}
				}
				break;
			default:
				break;
		}
		trans_release();
		FREELIST(data);
		return 1;
	}

	/* Step 3: perform the installation */
	alpm_list_t *packages = alpm_trans_get_add(config->handle);

	if(config->print) {
		print_packages(packages);
		trans_release();
		return 0;
	}

	/* print targets and ask user confirmation */
	if(packages == NULL) { /* we are done */
		printf(_(" there is nothing to do\n"));
		trans_release();
		return retval;
	}
	display_targets(alpm_trans_get_remove(config->handle), 0);
	display_targets(alpm_trans_get_add(config->handle), 1);
	printf("\n");
	int confirm = yesno(_("Proceed with installation?"));
	if(!confirm) {
		trans_release();
		return retval;
	}

	if(alpm_trans_commit(config->handle, &data) == -1) {
		enum _pmerrno_t err = alpm_errno(config->handle);
		pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
				alpm_strerror(err));
		switch(err) {
			case PM_ERR_FILE_CONFLICTS:
				for(i = data; i; i = alpm_list_next(i)) {
					pmfileconflict_t *conflict = alpm_list_getdata(i);
					switch(conflict->type) {
						case PM_FILECONFLICT_TARGET:
							printf(_("%s exists in both '%s' and '%s'\n"),
									conflict->file, conflict->target, conflict->ctarget);
							break;
						case PM_FILECONFLICT_FILESYSTEM:
							printf(_("%s: %s exists in filesystem\n"),
									conflict->target, conflict->file);
							break;
					}
				}
				break;
			case PM_ERR_PKG_INVALID:
			case PM_ERR_DLT_INVALID:
				for(i = data; i; i = alpm_list_next(i)) {
					char *filename = alpm_list_getdata(i);
					printf(_("%s is invalid or corrupted\n"), filename);
				}
				break;
			default:
				break;
		}
		FREELIST(data);
		trans_release();
		return 1;
	}

	if(trans_release() == -1) {
		retval = 1;
	}
	return retval;
}
Esempio n. 5
0
static int sync_prepare_execute(void)
{
	alpm_list_t *i, *packages, *data = NULL;
	int retval = 0;

	/* Step 2: "compute" the transaction based on targets and flags */
	if(alpm_trans_prepare(handle, &data) == -1) {
		alpm_errno_t err = alpm_errno(handle);
		printf("failed to prepare transaction (%s)\n", alpm_strerror(err));
		switch(err) {
			case ALPM_ERR_PKG_INVALID_ARCH:
				for(i = data; i; i = alpm_list_next(i)) {
					const char *pkg = i->data;
					printf("package %s does not have a valid architecture\n", pkg);
				}
				break;
			case ALPM_ERR_UNSATISFIED_DEPS:
				for(i = data; i; i = alpm_list_next(i)) {
					alpm_depmissing_t *miss = i->data;
					char *depstring = alpm_dep_compute_string(miss->depend);
					printf("%s: requires %s\n", miss->target, depstring);
					free(depstring);
				}
				break;
			case ALPM_ERR_CONFLICTING_DEPS:
				for(i = data; i; i = alpm_list_next(i)) {
					alpm_conflict_t *conflict = i->data;
					/* only print reason if it contains new information */
					if(conflict->reason->mod == ALPM_DEP_MOD_ANY) {
						printf("%s and %s are in conflict\n",
								conflict->package1, conflict->package2);
					} else {
						char *reason = alpm_dep_compute_string(conflict->reason);
						printf("%s and %s are in conflict (%s)\n",
								conflict->package1, conflict->package2, reason);
						free(reason);
					}
				}
				break;
			default:
				break;
		}
		retval = 1;
		goto cleanup;
	}

	packages = alpm_trans_get_add(handle);
	if(packages == NULL) {
		/* nothing to do: just exit without complaining */
			printf(" there is nothing to do\n");
		goto cleanup;
	}

	printf("\n");

	if(alpm_trans_commit(handle, &data) == -1) {
		alpm_errno_t err = alpm_errno(handle);
		printf("failed to commit transaction (%s)\n",
		        alpm_strerror(err));
		switch(err) {
			case ALPM_ERR_FILE_CONFLICTS:
				printf("unable to %s directory-file conflicts\n", "--force");
				for(i = data; i; i = alpm_list_next(i)) {
					alpm_fileconflict_t *conflict = i->data;
					switch(conflict->type) {
						case ALPM_FILECONFLICT_TARGET:
							printf("%s exists in both '%s' and '%s'\n",
									conflict->file, conflict->target, conflict->ctarget);
							break;
						case ALPM_FILECONFLICT_FILESYSTEM:
							printf("%s: %s exists in filesystem\n",
									conflict->target, conflict->file);
							break;
					}
				}
				break;
			case ALPM_ERR_PKG_INVALID:
			case ALPM_ERR_PKG_INVALID_CHECKSUM:
			case ALPM_ERR_PKG_INVALID_SIG:
			case ALPM_ERR_DLT_INVALID:
				for(i = data; i; i = alpm_list_next(i)) {
					const char *filename = i->data;
					printf("%s is invalid or corrupted\n", filename);
				}
				break;
			default:
				break;
		}
		/* TODO: stderr? */
		printf("Errors occurred, no packages were upgraded.\n");
		retval = 1;
		goto cleanup;
	}

	/* Step 4: release transaction resources */
cleanup:
	if(data) {
		FREELIST(data);
	}
	if(trans_release(handle) == -1) {
		retval = 1;
	}

	return retval;
}
Esempio n. 6
0
/**
 * @brief Remove a specified list of packages.
 *
 * @param targets a list of packages (as strings) to remove from the system
 *
 * @return 0 on success, 1 on failure
 */
int pacman_remove(alpm_list_t *targets)
{
    int retval = 0;
    alpm_list_t *i, *data = NULL;

    if(targets == NULL) {
        pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
        return(1);
    }

    /* Step 0: create a new transaction */
    if(trans_init(PM_TRANS_TYPE_REMOVE, config->flags) == -1) {
        return(1);
    }

    /* Step 1: add targets to the created transaction */
    for(i = targets; i; i = alpm_list_next(i)) {
        char *targ = alpm_list_getdata(i);
        if(alpm_trans_addtarget(targ) == -1) {
            if(pm_errno == PM_ERR_PKG_NOT_FOUND) {
                printf(_("%s not found, searching for group...\n"), targ);
                pmgrp_t *grp = alpm_db_readgrp(db_local, targ);
                if(grp == NULL) {
                    pm_fprintf(stderr, PM_LOG_ERROR, _("'%s': not found in local db\n"), targ);
                    retval = 1;
                    goto cleanup;
                } else {
                    alpm_list_t *p, *pkgnames = NULL;
                    /* convert packages to package names */
                    for(p = alpm_grp_get_pkgs(grp); p; p = alpm_list_next(p)) {
                        pmpkg_t *pkg = alpm_list_getdata(p);
                        pkgnames = alpm_list_add(pkgnames, (void *)alpm_pkg_get_name(pkg));
                    }
                    printf(_(":: group %s:\n"), targ);
                    list_display("   ", pkgnames);
                    int all = yesno(1, _("    Remove whole content?"));
                    for(p = pkgnames; p; p = alpm_list_next(p)) {
                        char *pkgn = alpm_list_getdata(p);
                        if(all || yesno(1, _(":: Remove %s from group %s?"), pkgn, targ)) {
                            if(alpm_trans_addtarget(pkgn) == -1) {
                                pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ,
                                           alpm_strerrorlast());
                                retval = 1;
                                alpm_list_free(pkgnames);
                                goto cleanup;
                            }
                        }
                    }
                    alpm_list_free(pkgnames);
                }
            } else {
                pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerrorlast());
                retval = 1;
                goto cleanup;
            }
        }
    }

    /* Step 2: prepare the transaction based on its type, targets and flags */
    if(alpm_trans_prepare(&data) == -1) {
        pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
                   alpm_strerrorlast());
        switch(pm_errno) {
        case PM_ERR_UNSATISFIED_DEPS:
            for(i = data; i; i = alpm_list_next(i)) {
                pmdepmissing_t *miss = alpm_list_getdata(i);
                pmdepend_t *dep = alpm_miss_get_dep(miss);
                char *depstring = alpm_dep_get_string(dep);
                printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss),
                       depstring);
                free(depstring);
            }
            FREELIST(data);
            break;
        default:
            break;
        }
        retval = 1;
        goto cleanup;
    }

    /* Warn user in case of dangerous operation */
    if(config->flags & PM_TRANS_FLAG_RECURSE ||
            config->flags & PM_TRANS_FLAG_CASCADE) {
        /* list transaction targets */
        alpm_list_t *pkglist = alpm_trans_get_pkgs();

        display_targets(pkglist, 0);
        printf("\n");

        /* get confirmation */
        if(yesno(1, _("Do you want to remove these packages?")) == 0) {
            retval = 1;
            goto cleanup;
        }
    }

    /* Step 3: actually perform the removal */
    if(alpm_trans_commit(NULL) == -1) {
        pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
                   alpm_strerrorlast());
        retval = 1;
    }

    /* Step 4: release transaction resources */
cleanup:
    if(trans_release() == -1) {
        retval = 1;
    }
    return(retval);
}
Esempio n. 7
0
static gboolean pacman_install_prepare (PacmanTransaction *transaction, const PacmanList *targets, GError **error) {
	const PacmanList *i;
	PacmanList *data = NULL;
	
	g_return_val_if_fail (transaction != NULL, FALSE);
	g_return_val_if_fail (targets != NULL, FALSE);
	
	if (pacman_transaction_get_installs (transaction) != NULL) {
		/* reinitialize so transaction can be prepared multiple times */
		if (!pacman_transaction_restart (transaction, error)) {
			return FALSE;
		}
	}
	
	for (i = targets; i != NULL; i = pacman_list_next (i)) {
		int result;
		gchar *target = (gchar *) pacman_list_get (i);
		
		if (strstr (target, "://") != NULL) {
			target = alpm_fetch_pkgurl (target);
			if (target == NULL) {
				g_set_error (error, PACMAN_ERROR, pm_errno, _("Could not download package with url '%s': %s"), (gchar *) pacman_list_get (i), alpm_strerrorlast ());
				return FALSE;
			}
			
			result = alpm_add_target (target);
			free (target);
		} else {
			result = alpm_add_target (target);
		}
		
		if (result < 0) {
			g_set_error (error, PACMAN_ERROR, pm_errno, _("Could not mark the file '%s' for installation: %s"), target, alpm_strerrorlast ());
			return FALSE;
		}
	}
	
	if (alpm_trans_prepare (&data) < 0) {
		if (pm_errno == PACMAN_ERROR_PACKAGE_WRONG_ARCHITECTURE) {
			gchar *packages = pacman_package_make_list (data);
			pacman_transaction_set_marked_packages (transaction, data);
			
			g_set_error (error, PACMAN_ERROR, pm_errno, _("The following packages have the wrong architecture: %s"), packages);
			g_free (packages);
			return FALSE;
		} else if (pm_errno == PACMAN_ERROR_DEPENDENCY_UNSATISFIED) {
			gchar *missing = pacman_missing_dependency_make_list (data);
			pacman_transaction_set_missing_dependencies (transaction, data);
			
			g_set_error (error, PACMAN_ERROR, pm_errno, _("Could not prepare transaction: %s"), missing);
			g_free (missing);
			return FALSE;
		} else if (pm_errno == PACMAN_ERROR_CONFLICT) {
			gchar *conflict = pacman_conflict_make_list (data);
			pacman_transaction_set_conflicts (transaction, data);
			
			g_set_error (error, PACMAN_ERROR, pm_errno, _("Could not prepare transaction: %s"), conflict);
			g_free (conflict);
			return FALSE;
		} else if (pm_errno == PACMAN_ERROR_FILE_CONFLICT) {
			gchar *conflict = pacman_file_conflict_make_list (data);
			pacman_transaction_set_file_conflicts (transaction, data);
			
			g_set_error (error, PACMAN_ERROR, pm_errno, _("Could not prepare transaction: %s"), conflict);
			g_free (conflict);
			return FALSE;
		} else if (data != NULL) {
			g_debug ("Possible memory leak for install error: %s\n", alpm_strerrorlast ());
		}
		
		g_set_error (error, PACMAN_ERROR, pm_errno, _("Could not prepare transaction: %s"), alpm_strerrorlast ());
		return FALSE;
	}
	
	return TRUE;
}
Esempio n. 8
0
File: remove.c Progetto: 7799/pacman
/**
 * @brief Remove a specified list of packages.
 *
 * @param targets a list of packages (as strings) to remove from the system
 *
 * @return 0 on success, 1 on failure
 */
int pacman_remove(alpm_list_t *targets)
{
	int retval = 0;
	alpm_list_t *i, *data = NULL;

	if(targets == NULL) {
		pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
		return 1;
	}

	/* Step 0: create a new transaction */
	if(trans_init(config->flags, 0) == -1) {
		return 1;
	}

	/* Step 1: add targets to the created transaction */
	for(i = targets; i; i = alpm_list_next(i)) {
		char *target = i->data;
		if(strncmp(target, "local/", 6) == 0) {
			target += 6;
		}
		if(remove_target(target) == -1) {
			retval = 1;
		}
	}

	if(retval == 1) {
		goto cleanup;
	}

	/* Step 2: prepare the transaction based on its type, targets and flags */
	if(alpm_trans_prepare(config->handle, &data) == -1) {
		alpm_errno_t err = alpm_errno(config->handle);
		pm_printf(ALPM_LOG_ERROR, _("failed to prepare transaction (%s)\n"),
		        alpm_strerror(err));
		switch(err) {
			case ALPM_ERR_UNSATISFIED_DEPS:
				for(i = data; i; i = alpm_list_next(i)) {
					alpm_depmissing_t *miss = i->data;
					char *depstring = alpm_dep_compute_string(miss->depend);
					colon_printf(_("%s: requires %s\n"), miss->target, depstring);
					free(depstring);
					alpm_depmissing_free(miss);
				}
				break;
			default:
				break;
		}
		alpm_list_free(data);
		retval = 1;
		goto cleanup;
	}

	/* Search for holdpkg in target list */
	int holdpkg = 0;
	for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
		alpm_pkg_t *pkg = i->data;
		if(alpm_list_find(config->holdpkg, alpm_pkg_get_name(pkg), fnmatch_cmp)) {
			pm_printf(ALPM_LOG_WARNING, _("%s is designated as a HoldPkg.\n"),
							alpm_pkg_get_name(pkg));
			holdpkg = 1;
		}
	}
	if(holdpkg && (noyes(_("HoldPkg was found in target list. Do you want to continue?")) == 0)) {
		retval = 1;
		goto cleanup;
	}

	/* Step 3: actually perform the removal */
	alpm_list_t *pkglist = alpm_trans_get_remove(config->handle);
	if(pkglist == NULL) {
		printf(_(" there is nothing to do\n"));
		goto cleanup; /* we are done */
	}

	if(config->print) {
		print_packages(pkglist);
		goto cleanup;
	}

	/* print targets and ask user confirmation */
	display_targets();
	printf("\n");
	if(yesno(_("Do you want to remove these packages?")) == 0) {
		retval = 1;
		goto cleanup;
	}

	if(alpm_trans_commit(config->handle, &data) == -1) {
		pm_printf(ALPM_LOG_ERROR, _("failed to commit transaction (%s)\n"),
		        alpm_strerror(alpm_errno(config->handle)));
		retval = 1;
	}

	FREELIST(data);

	/* Step 4: release transaction resources */
cleanup:
	if(trans_release() == -1) {
		retval = 1;
	}
	return retval;
}