Ejemplo n.º 1
0
int _alpm_upgrade_packages(alpm_handle_t *handle)
{
	size_t pkg_count, pkg_current;
	int skip_ldconfig = 0, ret = 0;
	alpm_list_t *targ;
	alpm_trans_t *trans = handle->trans;

	if(trans->add == NULL) {
		return 0;
	}

	pkg_count = alpm_list_count(trans->add);
	pkg_current = 1;

	/* loop through our package list adding/upgrading one at a time */
	for(targ = trans->add; targ; targ = targ->next) {
		alpm_pkg_t *newpkg = targ->data;

		if(handle->trans->state == STATE_INTERRUPTED) {
			return ret;
		}

		if(commit_single_pkg(handle, newpkg, pkg_current, pkg_count)) {
			/* something screwed up on the commit, abort the trans */
			trans->state = STATE_INTERRUPTED;
			handle->pm_errno = ALPM_ERR_TRANS_ABORT;
			/* running ldconfig at this point could possibly screw system */
			skip_ldconfig = 1;
			ret = -1;
		}

		pkg_current++;
	}

	if(!skip_ldconfig) {
		/* run ldconfig if it exists */
		_alpm_ldconfig(handle);
	}

	return ret;
}
Ejemplo n.º 2
0
/** Displays the list in table format
 *
 * @param title the tables title
 * @param header the column headers. column count is determined by the nr
 *               of headers
 * @param rows the rows to display as a list of lists of strings. the outer
 *             list represents the rows, the inner list the cells (= columns)
 * @param cols the number of columns available in the terminal
 * @return -1 if not enough terminal cols available, else 0
 */
static int table_display(const char *title, const alpm_list_t *header,
		const alpm_list_t *rows, unsigned short cols)
{
	const unsigned short padding = 2;
	const alpm_list_t *i;
	size_t *widths = NULL, totalcols, totalwidth;
	int *has_data = NULL;

	if(rows == NULL || header == NULL) {
		return 0;
	}

	totalcols = alpm_list_count(header);
	totalwidth = table_calc_widths(header, rows, padding, totalcols,
			&widths, &has_data);
	/* return -1 if terminal is not wide enough */
	if(totalwidth > cols) {
		pm_printf(ALPM_LOG_WARNING,
				_("insufficient columns available for table display\n"));
		return -1;
	}
	if(!totalwidth || !widths || !has_data) {
		return -1;
	}

	if(title != NULL) {
		printf("%s\n\n", title);
	}

	table_print_line(header, padding, totalcols, widths, has_data);
	printf("\n");

	for(i = rows; i; i = alpm_list_next(i)) {
		table_print_line(i->data, padding, totalcols, widths, has_data);
	}

	free(widths);
	free(has_data);
	return 0;
}
Ejemplo n.º 3
0
/* Search sync db for packages. Only works for 1 package now. */
static int sync_search(CURL *curl, alpm_list_t *targets)
{
	alpm_list_t *i, *j, *search_results;
	alpm_db_t *db;
	alpm_pkg_t *spkg;
	struct aurpkg_t *pkg;
	size_t listsz;

	search_results = query_aur(curl, targets->data, AUR_QUERY_SEARCH);
	if (search_results == NULL) {
		printf("Sorry, no results for %s\n", targets->data);
		return 0;
	}

	listsz = alpm_list_count(search_results);
	/* Sort by alphabetical order first */
	search_results = alpm_list_msort(search_results, listsz, aurpkg_name_cmp);

	/* Sort by votes */
	if (config->sort_votes) {
		search_results = alpm_list_msort(search_results, listsz, aurpkg_vote_cmp);
	}

	for (i = search_results; i; i = i->next) {
		pkg = (struct aurpkg_t *) i->data;
		printf("%saur/%s%s%s %s%s %s(%d)%s\n", color.bmag,
			   color.nocolor, color.bold, pkg->name,
			   color.bgreen, pkg->version,
			   color.votecol, pkg->votes, color.nocolor);
		printf("    %s\n", pkg->desc);
	}

	alpm_list_free_inner(search_results, (alpm_list_fn_free) aurpkg_free);
	alpm_list_free(search_results);

	return 0;
}
Ejemplo n.º 4
0
void show_results ()
{
	alpm_list_t *i_first;
	alpm_list_t *i;
	alpm_list_nav fn_nav=NULL;;
	alpm_list_fn_cmp fn_cmp=NULL;
	if (results!=NULL)
	{
		switch (config.sort)
		{
			case S_NAME: fn_cmp = (alpm_list_fn_cmp) results_cmp; break;
			case S_VOTE: fn_cmp = (alpm_list_fn_cmp) results_votes_cmp; break;
			case S_IDATE: fn_cmp = (alpm_list_fn_cmp) results_installdate_cmp; break;
			case S_ISIZE: fn_cmp = (alpm_list_fn_cmp) results_isize_cmp; break;
		}
		if (fn_cmp)
			results = alpm_list_msort (results, alpm_list_count (results), fn_cmp);
		if (config.rsort) {
			fn_nav = (alpm_list_nav) alpm_list_previous;
			i_first = alpm_list_last (results);
		} else {
			fn_nav = (alpm_list_nav) alpm_list_next;
			i_first = results;
		}
		for(i = i_first; i; i = fn_nav(i))
		{
			results_t *r = i->data;
			if (r->type == R_ALPM_PKG)
				print_package ("", r->ele, alpm_pkg_get_str);
			else if (r->type == R_AUR_PKG)
				print_package ("", r->ele, aur_get_str);
		}
		alpm_list_free_inner (results, (alpm_list_fn_free) results_free);
		alpm_list_free (results);
		results = NULL;
	}
}
Ejemplo n.º 5
0
/* prepare a list of pkgs to display */
static void _display_targets(alpm_list_t *targets, int verbose)
{
	char *str;
	const char *label;
	double size;
	off_t isize = 0, rsize = 0, dlsize = 0;
	unsigned short cols;
	alpm_list_t *i, *rows = NULL, *names = NULL;

	if(!targets) {
		return;
	}

	/* gather package info */
	for(i = targets; i; i = alpm_list_next(i)) {
		pm_target_t *target = i->data;

		if(target->install) {
			dlsize += alpm_pkg_download_size(target->install);
			isize += alpm_pkg_get_isize(target->install);
		}
		if(target->remove) {
			/* add up size of all removed packages */
			rsize += alpm_pkg_get_isize(target->remove);
		}
	}

	/* form data for both verbose and non-verbose display */
	for(i = targets; i; i = alpm_list_next(i)) {
		pm_target_t *target = i->data;

		rows = alpm_list_add(rows, create_verbose_row(target));
		if(target->install) {
			pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install),
					alpm_pkg_get_version(target->install));
		} else if(isize == 0) {
			pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->remove),
					alpm_pkg_get_version(target->remove));
		} else {
			pm_asprintf(&str, "%s-%s [removal]", alpm_pkg_get_name(target->remove),
					alpm_pkg_get_version(target->remove));
		}
		names = alpm_list_add(names, str);
	}

	/* print to screen */
	pm_asprintf(&str, _("Packages (%d):"), alpm_list_count(targets));
	printf("\n");

	cols = getcols(fileno(stdout));
	if(verbose) {
		alpm_list_t *header = create_verbose_header();
		if(table_display(str, header, rows, cols) != 0) {
			/* fallback to list display if table wouldn't fit */
			list_display(str, names, cols);
		}
		alpm_list_free(header);
	} else {
		list_display(str, names, cols);
	}
	printf("\n");

	/* rows is a list of lists of strings, free inner lists here */
	for(i = rows; i; i = alpm_list_next(i)) {
		alpm_list_t *lp = i->data;
		FREELIST(lp);
	}
	alpm_list_free(rows);
	FREELIST(names);
	free(str);

	if(dlsize > 0 || config->op_s_downloadonly) {
		size = humanize_size(dlsize, 'M', 2, &label);
		printf(_("Total Download Size:    %.2f %s\n"), size, label);
	}
	if(!config->op_s_downloadonly) {
		if(isize > 0) {
			size = humanize_size(isize, 'M', 2, &label);
			printf(_("Total Installed Size:   %.2f %s\n"), size, label);
		}
		if(rsize > 0 && isize == 0) {
			size = humanize_size(rsize, 'M', 2, &label);
			printf(_("Total Removed Size:     %.2f %s\n"), size, label);
		}
		/* only show this net value if different from raw installed size */
		if(isize > 0 && rsize > 0) {
			size = humanize_size(isize - rsize, 'M', 2, &label);
			printf(_("Net Upgrade Size:       %.2f %s\n"), size, label);
		}
	}
}
Ejemplo n.º 6
0
/**
 * pacman_list_length:
 * @list: A #PacmanList.
 *
 * Gets the number of items in @list.
 *
 * Returns: The length of @list.
 */
guint pacman_list_length (const PacmanList *list) {
	return alpm_list_count (list);
}
Ejemplo n.º 7
0
alpm_list_t* alpm_list_sort_data (alpm_list_t *list, alpm_list_fn_cmp fn) {
	list = alpm_list_msort (list, alpm_list_count (list), fn);
	return list;
}
Ejemplo n.º 8
0
int _alpm_check_diskspace(alpm_handle_t *handle)
{
	alpm_list_t *mount_points, *i;
	alpm_mountpoint_t *root_mp;
	size_t replaces = 0, current = 0, numtargs;
	int error = 0;
	alpm_list_t *targ;
	alpm_trans_t *trans = handle->trans;

	numtargs = alpm_list_count(trans->add);
	mount_points = mount_point_list(handle);
	if(mount_points == NULL) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not determine filesystem mount points\n"));
		return -1;
	}
	root_mp = match_mount_point(mount_points, handle->root);
	if(root_mp == NULL) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not determine root mount point %s\n"),
				handle->root);
		error = 1;
		goto finish;
	}

	replaces = alpm_list_count(trans->remove);
	if(replaces) {
		numtargs += replaces;
		for(targ = trans->remove; targ; targ = targ->next, current++) {
			alpm_pkg_t *local_pkg;
			int percent = (current * 100) / numtargs;
			PROGRESS(handle, ALPM_PROGRESS_DISKSPACE_START, "", percent,
					numtargs, current);

			local_pkg = targ->data;
			calculate_removed_size(handle, mount_points, local_pkg);
		}
	}

	for(targ = trans->add; targ; targ = targ->next, current++) {
		alpm_pkg_t *pkg, *local_pkg;
		int percent = (current * 100) / numtargs;
		PROGRESS(handle, ALPM_PROGRESS_DISKSPACE_START, "", percent,
				numtargs, current);

		pkg = targ->data;
		/* is this package already installed? */
		local_pkg = _alpm_db_get_pkgfromcache(handle->db_local, pkg->name);
		if(local_pkg) {
			calculate_removed_size(handle, mount_points, local_pkg);
		}
		calculate_installed_size(handle, mount_points, pkg);

		for(i = mount_points; i; i = i->next) {
			alpm_mountpoint_t *data = i->data;
			if(data->blocks_needed > data->max_blocks_needed) {
				data->max_blocks_needed = data->blocks_needed;
			}
		}
	}

	PROGRESS(handle, ALPM_PROGRESS_DISKSPACE_START, "", 100,
			numtargs, current);

	for(i = mount_points; i; i = i->next) {
		alpm_mountpoint_t *data = i->data;
		if(data->used && data->read_only) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("Partition %s is mounted read only\n"),
					data->mount_dir);
			error = 1;
		} else if(data->used & USED_INSTALL && check_mountpoint(handle, data)) {
			error = 1;
		}
	}

finish:
	mount_point_list_free(mount_points);

	if(error) {
		RET_ERR(handle, ALPM_ERR_DISK_SPACE, -1);
	}

	return 0;
}
Ejemplo n.º 9
0
/* callback to handle questions from libalpm transactions (yes/no) */
void cb_question(alpm_question_t *question)
{
	if(config->print) {
		if(question->type == ALPM_QUESTION_INSTALL_IGNOREPKG) {
			question->any.answer = 1;
		} else {
			question->any.answer = 0;
		}
		return;
	}
	switch(question->type) {
		case ALPM_QUESTION_INSTALL_IGNOREPKG:
			{
				alpm_question_install_ignorepkg_t *q = &question->install_ignorepkg;
				if(!config->op_s_downloadonly) {
					q->install = yesno(_("%s is in IgnorePkg/IgnoreGroup. Install anyway?"),
							alpm_pkg_get_name(q->pkg));
				} else {
					q->install = 1;
				}
			}
			break;
		case ALPM_QUESTION_REPLACE_PKG:
			{
				alpm_question_replace_t *q = &question->replace;
				q->replace = yesno(_("Replace %s with %s/%s?"),
						alpm_pkg_get_name(q->oldpkg),
						alpm_db_get_name(q->newdb),
						alpm_pkg_get_name(q->newpkg));
			}
			break;
		case ALPM_QUESTION_CONFLICT_PKG:
			{
				alpm_question_conflict_t *q = &question->conflict;
				/* print conflict only if it contains new information */
				if(strcmp(q->conflict->package1, q->conflict->reason->name) == 0
						|| strcmp(q->conflict->package2, q->conflict->reason->name) == 0) {
					q->remove = noyes(_("%s and %s are in conflict. Remove %s?"),
							q->conflict->package1,
							q->conflict->package2,
							q->conflict->package2);
				} else {
					q->remove = noyes(_("%s and %s are in conflict (%s). Remove %s?"),
							q->conflict->package1,
							q->conflict->package2,
							q->conflict->reason->name,
							q->conflict->package2);
				}
			}
			break;
		case ALPM_QUESTION_REMOVE_PKGS:
			{
				alpm_question_remove_pkgs_t *q = &question->remove_pkgs;
				alpm_list_t *namelist = NULL, *i;
				size_t count = 0;
				for(i = q->packages; i; i = i->next) {
					namelist = alpm_list_add(namelist,
							(char *)alpm_pkg_get_name(i->data));
					count++;
				}
				colon_printf(_n(
							"The following package cannot be upgraded due to unresolvable dependencies:\n",
							"The following packages cannot be upgraded due to unresolvable dependencies:\n",
							count));
				list_display("     ", namelist, getcols());
				printf("\n");
				q->skip = noyes(_n(
							"Do you want to skip the above package for this upgrade?",
							"Do you want to skip the above packages for this upgrade?",
							count));
				alpm_list_free(namelist);
			}
			break;
		case ALPM_QUESTION_SELECT_PROVIDER:
			{
				alpm_question_select_provider_t *q = &question->select_provider;
				size_t count = alpm_list_count(q->providers);
				char *depstring = alpm_dep_compute_string(q->depend);
				colon_printf(_n("There is %zd provider available for %s\n",
						"There are %zd providers available for %s:\n", count),
						count, depstring);
				free(depstring);
				select_display(q->providers);
				q->use_index = select_question(count);
			}
			break;
		case ALPM_QUESTION_CORRUPTED_PKG:
			{
				alpm_question_corrupted_t *q = &question->corrupted;
				q->remove = yesno(_("File %s is corrupted (%s).\n"
							"Do you want to delete it?"),
						q->filepath,
						alpm_strerror(q->reason));
			}
			break;
		case ALPM_QUESTION_IMPORT_KEY:
			{
				alpm_question_import_key_t *q = &question->import_key;
				char created[12];
				time_t time = (time_t)q->key->created;
				strftime(created, 12, "%Y-%m-%d", localtime(&time));

				if(q->key->revoked) {
					q->import = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s (revoked)?"),
							q->key->length, q->key->pubkey_algo, q->key->fingerprint, q->key->uid, created);
				} else {
					q->import = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s?"),
							q->key->length, q->key->pubkey_algo, q->key->fingerprint, q->key->uid, created);
				}
			}
			break;
	}
	if(config->noask) {
		if(config->ask & question->type) {
			/* inverse the default answer */
			question->any.answer = !question->any.answer;
		}
	}
}
Ejemplo n.º 10
0
int _alpm_sync_commit(alpm_handle_t *handle, alpm_list_t **data)
{
	alpm_list_t *i;
	alpm_list_t *deltas = NULL;
	size_t numtargs, current = 0, replaces = 0;
	int errors;
	alpm_trans_t *trans = handle->trans;

	if(download_files(handle, &deltas)) {
		alpm_list_free(deltas);
		return -1;
	}

	if(validate_deltas(handle, deltas, data)) {
		alpm_list_free(deltas);
		return -1;
	}
	alpm_list_free(deltas);

	/* Check integrity of packages */
	numtargs = alpm_list_count(trans->add);
	EVENT(trans, ALPM_TRANS_EVT_INTEGRITY_START, NULL, NULL);

	errors = 0;

	for(i = trans->add; i; i = i->next, current++) {
		alpm_pkg_t *spkg = i->data;
		int percent = (current * 100) / numtargs;
		const char *filename;
		char *filepath;
		alpm_siglevel_t level;

		PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", percent,
				numtargs, current);
		if(spkg->origin == PKG_FROM_FILE) {
			continue; /* pkg_load() has been already called, this package is valid */
		}

		filename = alpm_pkg_get_filename(spkg);
		filepath = _alpm_filecache_find(handle, filename);
		alpm_db_t *sdb = alpm_pkg_get_db(spkg);
		level = alpm_db_get_siglevel(sdb);

		/* load the package file and replace pkgcache entry with it in the target list */
		/* TODO: alpm_pkg_get_db() will not work on this target anymore */
		_alpm_log(handle, ALPM_LOG_DEBUG,
				"replacing pkgcache entry with package file for target %s\n",
				spkg->name);
		alpm_pkg_t *pkgfile =_alpm_pkg_load_internal(handle, filepath, 1, spkg->md5sum,
				spkg->base64_sig, level);
		if(!pkgfile) {
			errors++;
			*data = alpm_list_add(*data, strdup(filename));
			FREE(filepath);
			continue;
		}
		FREE(filepath);
		pkgfile->reason = spkg->reason; /* copy over install reason */
		i->data = pkgfile;
		_alpm_pkg_free_trans(spkg); /* spkg has been removed from the target list */
	}

	PROGRESS(trans, ALPM_TRANS_PROGRESS_INTEGRITY_START, "", 100,
			numtargs, current);
	EVENT(trans, ALPM_TRANS_EVT_INTEGRITY_DONE, NULL, NULL);


	if(errors) {
		RET_ERR(handle, ALPM_ERR_PKG_INVALID, -1);
	}

	if(trans->flags & ALPM_TRANS_FLAG_DOWNLOADONLY) {
		return 0;
	}

	trans->state = STATE_COMMITING;

	replaces = alpm_list_count(trans->remove);

	/* fileconflict check */
	if(!(trans->flags & ALPM_TRANS_FLAG_FORCE)) {
		EVENT(trans, ALPM_TRANS_EVT_FILECONFLICTS_START, NULL, NULL);

		_alpm_log(handle, ALPM_LOG_DEBUG, "looking for file conflicts\n");
		alpm_list_t *conflict = _alpm_db_find_fileconflicts(handle,
				trans->add, trans->remove);
		if(conflict) {
			if(data) {
				*data = conflict;
			} else {
				alpm_list_free_inner(conflict, (alpm_list_fn_free)_alpm_fileconflict_free);
				alpm_list_free(conflict);
			}
			RET_ERR(handle, ALPM_ERR_FILE_CONFLICTS, -1);
		}

		EVENT(trans, ALPM_TRANS_EVT_FILECONFLICTS_DONE, NULL, NULL);
	}

	/* check available disk space */
	if(handle->checkspace) {
		EVENT(trans, ALPM_TRANS_EVT_DISKSPACE_START, NULL, NULL);

		_alpm_log(handle, ALPM_LOG_DEBUG, "checking available disk space\n");
		if(_alpm_check_diskspace(handle) == -1) {
			_alpm_log(handle, ALPM_LOG_ERROR, "%s\n", _("not enough free disk space"));
			return -1;
		}

		EVENT(trans, ALPM_TRANS_EVT_DISKSPACE_DONE, NULL, NULL);
	}

	/* remove conflicting and to-be-replaced packages */
	if(replaces) {
		_alpm_log(handle, ALPM_LOG_DEBUG, "removing conflicting and to-be-replaced packages\n");
		/* we want the frontend to be aware of commit details */
		if(_alpm_remove_packages(handle) == -1) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not commit removal transaction\n"));
			return -1;
		}
	}

	/* install targets */
	_alpm_log(handle, ALPM_LOG_DEBUG, "installing packages\n");
	if(_alpm_upgrade_packages(handle) == -1) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not commit transaction\n"));
		return -1;
	}

	return 0;
}
Ejemplo n.º 11
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)
{
    int retval = 0, *file_is_remote;
    alpm_list_t *i;
    unsigned int n, num_targets;

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

    num_targets = alpm_list_count(targets);

    /* Check for URL targets and process them */
    file_is_remote = malloc(num_targets * sizeof(int));
    if(file_is_remote == NULL) {
        pm_printf(ALPM_LOG_ERROR, _("memory exhausted\n"));
        return 1;
    }

    for(i = targets, n = 0; i; i = alpm_list_next(i), n++) {
        if(strstr(i->data, "://")) {
            char *str = alpm_fetch_pkgurl(config->handle, i->data);
            if(str == NULL) {
                pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
                          (char *)i->data, alpm_strerror(alpm_errno(config->handle)));
                retval = 1;
            } else {
                free(i->data);
                i->data = str;
                file_is_remote[n] = 1;
            }
        } else {
            file_is_remote[n] = 0;
        }
    }

    if(retval) {
        goto fail_free;
    }

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

    printf(_("loading packages...\n"));
    /* add targets to the created transaction */
    for(i = targets, n = 0; i; i = alpm_list_next(i), n++) {
        const char *targ = i->data;
        alpm_pkg_t *pkg;
        int siglevel;

        if(file_is_remote[n]) {
            siglevel = alpm_option_get_remote_file_siglevel(config->handle);
        } else {
            siglevel = alpm_option_get_local_file_siglevel(config->handle);
        }

        if(alpm_pkg_load(config->handle, targ, 1, siglevel, &pkg) != 0) {
            pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
                      targ, alpm_strerror(alpm_errno(config->handle)));
            retval = 1;
            continue;
        }
        if(alpm_add_pkg(config->handle, pkg) == -1) {
            pm_printf(ALPM_LOG_ERROR, "'%s': %s\n",
                      targ, alpm_strerror(alpm_errno(config->handle)));
            alpm_pkg_free(pkg);
            retval = 1;
            continue;
        }
        config->explicit_adds = alpm_list_add(config->explicit_adds, pkg);
    }

    if(retval) {
        goto fail_release;
    }

    free(file_is_remote);

    /* now that targets are resolved, we can hand it all off to the sync code */
    return sync_prepare_execute();

fail_release:
    trans_release();
fail_free:
    free(file_is_remote);

    return retval;
}
Ejemplo n.º 12
0
int powaur_backup(alpm_list_t *targets)
{
	int ret = 0;
	char localdb[PATH_MAX];
	struct archive *a;
	struct archive_entry *entry;
	struct stat st;

	char cwd[PATH_MAX];
	char backup_dest[PATH_MAX];
	char backup[MINI_BUFSZ];

	time_t time_now;
	struct tm tm_st;

	if (targets != NULL && alpm_list_count(targets) != 1) {
		pw_fprintf(PW_LOG_ERROR, stderr, "-B only takes 1 argument.\n");
		return -1;
	}

	a = archive_write_new();
	if (!a) {
		return error(PW_ERR_ARCHIVE_CREATE);
	}

	archive_write_set_compression_bzip2(a);
	archive_write_set_format_pax_restricted(a);

	/* Filename = pacman-YYYY-MM-DD_HHhMM.tar.bz2 */
	time(&time_now);
	localtime_r(&time_now, &tm_st);
	strftime(backup, MINI_BUFSZ, "pacman-%Y-%m-%d_%Hh%M.tar.bz2", &tm_st);

	if (!getcwd(cwd, PATH_MAX)) {
		error(PW_ERR_GETCWD);
		ret = -1;
		goto cleanup;
	}

	/* Get full path */
	if (targets) {
		snprintf(backup_dest, PATH_MAX, "%s/%s", targets->data, backup);
	} else {
		snprintf(backup_dest, PATH_MAX, "%s/%s", cwd, backup);
	}

	if (archive_write_open_filename(a, backup_dest) != ARCHIVE_OK) {
		PW_SETERRNO(PW_ERR_ARCHIVE_OPEN);
		ret = -1;
		goto cleanup;
	}

	if (ret = chdir(pacman_dbpath)) {
		error(PW_ERR_CHDIR, pacman_dbpath);
		goto restore_cwd;
	}

	/* Create entry for the current directory. */
	entry = archive_entry_new();
	if (!entry) {
		error(PW_ERR_ARCHIVE_ENTRY);
		goto restore_cwd;
	}

	snprintf(localdb, PATH_MAX, "%s", "local");
	if (ret = stat(localdb, &st)) {
		error(PW_ERR_STAT, localdb);
		goto free_entry;
	}

	archive_entry_set_pathname(entry, localdb);
	archive_entry_copy_stat(entry, &st);
	archive_write_header(a, entry);

	pw_printf(PW_LOG_INFO, "Saving pacman database in %s\n", backup_dest);

	ret = write_dir_archive(localdb, a);

	if (!ret) {
		pw_printf(PW_LOG_INFO, "Pacman database successfully saved in %s\n",
				  backup_dest);
	} else {
		pw_fprintf(PW_LOG_ERROR, stderr, "Pacman database not saved.\n");
	}

free_entry:
	archive_entry_free(entry);

restore_cwd:
	if (chdir(cwd)) {
		PW_SETERRNO(PW_ERR_RESTORECWD);
		ret = -1;
	}

cleanup:
	archive_write_finish(a);
	return ret;
}
Ejemplo n.º 13
0
static int sync_db_populate(alpm_db_t *db)
{
	const char *dbpath;
	size_t est_count;
	int count = 0;
	struct stat buf;
	struct archive *archive;
	struct archive_entry *entry;
	alpm_pkg_t *pkg = NULL;

	if(db->status & DB_STATUS_INVALID) {
		RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1);
	}
	if(db->status & DB_STATUS_MISSING) {
		RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1);
	}

	if((archive = archive_read_new()) == NULL) {
		RET_ERR(db->handle, ALPM_ERR_LIBARCHIVE, -1);
	}

	archive_read_support_compression_all(archive);
	archive_read_support_format_all(archive);

	dbpath = _alpm_db_path(db);
	if(!dbpath) {
		/* pm_errno set in _alpm_db_path() */
		return -1;
	}

	_alpm_log(db->handle, ALPM_LOG_DEBUG, "opening database archive %s\n", dbpath);

	if(archive_read_open_filename(archive, dbpath,
				ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
		_alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath,
				archive_error_string(archive));
		archive_read_finish(archive);
		RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
	}
	if(stat(dbpath, &buf) != 0) {
		RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1);
	}
	est_count = estimate_package_count(&buf, archive);

	/* initialize hash at 66% full */
	db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2);
	if(db->pkgcache == NULL) {
		RET_ERR(db->handle, ALPM_ERR_MEMORY, -1);
	}

	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
		mode_t mode = archive_entry_mode(entry);
		if(S_ISDIR(mode)) {
			continue;
		} else {
			/* we have desc, depends or deltas - parse it */
			if(sync_db_read(db, archive, entry, &pkg) != 0) {
				_alpm_log(db->handle, ALPM_LOG_ERROR,
						_("could not parse package description file '%s' from db '%s'\n"),
						archive_entry_pathname(entry), db->treename);
				continue;
			}
		}
	}

	count = alpm_list_count(db->pkgcache->list);

	if(count > 0) {
		db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp);
	}
	archive_read_finish(archive);
	_alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n",
			count, db->treename);

	return count;
}
Ejemplo n.º 14
0
/* Find file conflicts that may occur during the transaction with two checks:
 * 1: check every target against every target
 * 2: check every target against the filesystem */
alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, char *root)
{
	alpm_list_t *i, *conflicts = NULL;
	alpm_list_t *targets = trans->packages;
	int numtargs = alpm_list_count(targets);
	int current;

	ALPM_LOG_FUNC;

	if(db == NULL || targets == NULL || root == NULL) {
		return(NULL);
	}

	/* TODO this whole function needs a huge change, which hopefully will
	 * be possible with real transactions. Right now we only do half as much
	 * here as we do when we actually extract files in add.c with our 12
	 * different cases. */
	for(current = 1, i = targets; i; i = i->next, current++) {
		alpm_list_t *j, *k, *tmpfiles = NULL;
		pmpkg_t *p1, *p2, *dbpkg;
		char path[PATH_MAX+1];

		p1 = i->data;
		if(!p1) {
			continue;
		}

		double percent = (double)current / numtargs;
		PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", (percent * 100),
		         numtargs, current);
		/* CHECK 1: check every target against every target */
		_alpm_log(PM_LOG_DEBUG, "searching for file conflicts: %s\n",
								alpm_pkg_get_name(p1));
		for(j = i->next; j; j = j->next) {
			p2 = j->data;
			if(!p2) {
				continue;
			}
			tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2));

			if(tmpfiles) {
				for(k = tmpfiles; k; k = k->next) {
					snprintf(path, PATH_MAX, "%s%s", root, (char *)k->data);
					conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_TARGET, path,
							alpm_pkg_get_name(p1), alpm_pkg_get_name(p2));
				}
				FREELIST(tmpfiles);
			}
		}

		/* declarations for second check */
		struct stat lsbuf, sbuf;
		char *filestr = NULL;

		/* CHECK 2: check every target against the filesystem */
		_alpm_log(PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", p1->name);
		dbpkg = _alpm_db_get_pkgfromcache(db, p1->name);

		/* Do two different checks here. f the package is currently installed,
		 * then only check files that are new in the new package. If the package
		 * is not currently installed, then simply stat the whole filelist */
		if(dbpkg) {
			/* older ver of package currently installed */
			tmpfiles = chk_filedifference(alpm_pkg_get_files(p1),
					alpm_pkg_get_files(dbpkg));
		} else {
			/* no version of package currently installed */
			tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1));
		}

		/* loop over each file to be installed */
		for(j = tmpfiles; j; j = j->next) {
			int skip_conflict = 0;
			filestr = j->data;

			snprintf(path, PATH_MAX, "%s%s", root, filestr);

			/* stat the file - if it exists, do some checks */
			if(_alpm_lstat(path, &lsbuf) != 0) {
				continue;
			}
			stat(path, &sbuf);

			if(path[strlen(path)-1] == '/') {
				if(S_ISDIR(lsbuf.st_mode)) {
					_alpm_log(PM_LOG_DEBUG, "%s is a directory, not a conflict\n", path);
					skip_conflict = 1;
				} else if(S_ISLNK(lsbuf.st_mode) && S_ISDIR(sbuf.st_mode)) {
					_alpm_log(PM_LOG_DEBUG,
							"%s is a symlink to a dir, hopefully not a conflict\n", path);
					skip_conflict = 1;
				}
			}
			if(!skip_conflict) {
				_alpm_log(PM_LOG_DEBUG, "checking possible conflict: %s\n", path);

				/* Look at all the targets to see if file has changed hands */
				int resolved_conflict = 0; /* have we acted on this conflict? */
				for(k = targets; k; k = k->next) {
					p2 = k->data;
					if(!p2 || strcmp(p1->name, p2->name) == 0) {
						continue;
					}

					pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name);

					/* Check if it used to exist in a package, but doesn't anymore */
					alpm_list_t *pkgfiles, *localfiles; /* added for readability */
					pkgfiles = alpm_pkg_get_files(p2);
					localfiles = alpm_pkg_get_files(localp2);

					if(localp2 && !alpm_list_find_str(pkgfiles, filestr)
						 && alpm_list_find_str(localfiles, filestr)) {
						/* skip removal of file, but not add. this will prevent a second
						 * package from removing the file when it was already installed
						 * by its new owner (whether the file is in backup array or not */
						trans->skip_remove = alpm_list_add(trans->skip_remove, strdup(path));
						_alpm_log(PM_LOG_DEBUG, "file changed packages, adding to remove skiplist: %s\n", filestr);
						resolved_conflict = 1;
						break;
					}
				}
				if(!resolved_conflict) {
					_alpm_log(PM_LOG_DEBUG, "file found in conflict: %s\n", path);
					conflicts = add_fileconflict(conflicts, PM_FILECONFLICT_FILESYSTEM,
							path, p1->name, NULL);
				}
			}
		}
		FREELIST(tmpfiles);
	}

	return(conflicts);
}
Ejemplo n.º 15
0
/* TODO this is one of the worst ever functions written. void *data ? wtf */
void cb_question(alpm_question_t event, void *data1, void *data2,
                   void *data3, int *response)
{
	if(config->print) {
		if(event == ALPM_QUESTION_INSTALL_IGNOREPKG) {
			*response = 1;
		} else {
			*response = 0;
		}
		return;
	}
	switch(event) {
		case ALPM_QUESTION_INSTALL_IGNOREPKG:
			if(!config->op_s_downloadonly) {
				*response = yesno(_("%s is in IgnorePkg/IgnoreGroup. Install anyway?"),
								alpm_pkg_get_name(data1));
			} else {
				*response = 1;
			}
			break;
		case ALPM_QUESTION_REPLACE_PKG:
			*response = yesno(_("Replace %s with %s/%s?"),
					alpm_pkg_get_name(data1),
					(char *)data3,
					alpm_pkg_get_name(data2));
			break;
		case ALPM_QUESTION_CONFLICT_PKG:
			/* data parameters: target package, local package, conflict (strings) */
			/* print conflict only if it contains new information */
			if(strcmp(data1, data3) == 0 || strcmp(data2, data3) == 0) {
				*response = noyes(_("%s and %s are in conflict. Remove %s?"),
						(char *)data1,
						(char *)data2,
						(char *)data2);
			} else {
				*response = noyes(_("%s and %s are in conflict (%s). Remove %s?"),
						(char *)data1,
						(char *)data2,
						(char *)data3,
						(char *)data2);
			}
			break;
		case ALPM_QUESTION_REMOVE_PKGS:
			{
				alpm_list_t *unresolved = data1;
				alpm_list_t *namelist = NULL, *i;
				size_t count = 0;
				for(i = unresolved; i; i = i->next) {
					namelist = alpm_list_add(namelist,
							(char *)alpm_pkg_get_name(i->data));
					count++;
				}
				colon_printf(_n(
							"The following package cannot be upgraded due to unresolvable dependencies:\n",
							"The following packages cannot be upgraded due to unresolvable dependencies:\n",
							count));
				list_display("     ", namelist, getcols(fileno(stdout)));
				printf("\n");
				*response = noyes(_n(
							"Do you want to skip the above package for this upgrade?",
							"Do you want to skip the above packages for this upgrade?",
							count));
				alpm_list_free(namelist);
			}
			break;
		case ALPM_QUESTION_SELECT_PROVIDER:
			{
				alpm_list_t *providers = data1;
				size_t count = alpm_list_count(providers);
				char *depstring = alpm_dep_compute_string((alpm_depend_t *)data2);
				colon_printf(_("There are %zd providers available for %s:\n"), count,
						depstring);
				free(depstring);
				select_display(providers);
				*response = select_question(count);
			}
			break;
		case ALPM_QUESTION_CORRUPTED_PKG:
			*response = yesno(_("File %s is corrupted (%s).\n"
						"Do you want to delete it?"),
					(char *)data1,
					alpm_strerror(*(alpm_errno_t *)data2));
			break;
		case ALPM_QUESTION_IMPORT_KEY:
			{
				alpm_pgpkey_t *key = data1;
				char created[12];
				time_t time = (time_t)key->created;
				strftime(created, 12, "%Y-%m-%d", localtime(&time));

				if(key->revoked) {
					*response = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s (revoked)?"),
							key->length, key->pubkey_algo, key->fingerprint, key->uid, created);
				} else {
					*response = yesno(_("Import PGP key %d%c/%s, \"%s\", created: %s?"),
							key->length, key->pubkey_algo, key->fingerprint, key->uid, created);
				}
			}
			break;
	}
	if(config->noask) {
		if(config->ask & event) {
			/* inverse the default answer */
			*response = !*response;
		}
	}
}
Ejemplo n.º 16
0
static alpm_list_t *mount_point_list(alpm_handle_t *handle)
{
	alpm_list_t *mount_points = NULL, *ptr;
	alpm_mountpoint_t *mp;

#if defined(HAVE_GETMNTENT) && defined(HAVE_MNTENT_H)
	/* Linux */
	struct mntent *mnt;
	FILE *fp;

	fp = setmntent(MOUNTED, "r");

	if(fp == NULL) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not open file: %s: %s\n"),
				MOUNTED, strerror(errno));
		return NULL;
	}

	while((mnt = getmntent(fp))) {
		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
		STRDUP(mp->mount_dir, mnt->mnt_dir, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
		mp->mount_dir_len = strlen(mp->mount_dir);

		mount_points = alpm_list_add(mount_points, mp);
	}

	endmntent(fp);
#elif defined(HAVE_GETMNTENT) && defined(HAVE_MNTTAB_H)
	/* Solaris, Illumos */
	struct mnttab mnt;
	FILE *fp;
	int ret;

	fp = fopen("/etc/mnttab", "r");

	if(fp == NULL) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"),
				"/etc/mnttab", strerror(errno));
		return NULL;
	}

	while((ret = getmntent(fp, &mnt)) == 0) {
		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
		STRDUP(mp->mount_dir, mnt->mnt_mountp,  free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
		mp->mount_dir_len = strlen(mp->mount_dir);

		mount_points = alpm_list_add(mount_points, mp);
	}
	/* -1 == EOF */
	if(ret != -1) {
		_alpm_log(handle, ALPM_LOG_WARNING,
				_("could not get filesystem information\n"));
	}

	fclose(fp);
#elif defined(HAVE_GETMNTINFO)
	/* FreeBSD (statfs), NetBSD (statvfs), OpenBSD (statfs), OS X (statfs) */
	int entries;
	FSSTATSTYPE *fsp;

	entries = getmntinfo(&fsp, MNT_NOWAIT);

	if(entries < 0) {
		_alpm_log(handle, ALPM_LOG_ERROR,
				_("could not get filesystem information\n"));
		return NULL;
	}

	for(; entries-- > 0; fsp++) {
		CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
		STRDUP(mp->mount_dir, fsp->f_mntonname, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL));
		mp->mount_dir_len = strlen(mp->mount_dir);
		memcpy(&(mp->fsp), fsp, sizeof(FSSTATSTYPE));
#if defined(HAVE_GETMNTINFO_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FLAG)
		mp->read_only = fsp->f_flag & ST_RDONLY;
#elif defined(HAVE_GETMNTINFO_STATFS) && defined(HAVE_STRUCT_STATFS_F_FLAGS)
		mp->read_only = fsp->f_flags & MNT_RDONLY;
#endif

		/* we don't support lazy loading on this platform */
		mp->fsinfo_loaded = MOUNT_FSINFO_LOADED;

		mount_points = alpm_list_add(mount_points, mp);
	}
#endif

	mount_points = alpm_list_msort(mount_points, alpm_list_count(mount_points),
			mount_point_cmp);
	for(ptr = mount_points; ptr != NULL; ptr = ptr->next) {
		mp = ptr->data;
		_alpm_log(handle, ALPM_LOG_DEBUG, "discovered mountpoint: %s\n", mp->mount_dir);
	}
	return mount_points;
}
Ejemplo n.º 17
0
/* Lists detailed information about targets */
static int sync_info(CURL *curl, alpm_list_t *targets)
{
	int found, ret, pkgcount;
	alpm_list_t *i, *j, *results;
	alpm_list_t *free_list = NULL;
	alpm_list_t *syncdbs = alpm_option_get_syncdbs(config->handle);
	alpm_pkg_t *spkg;

	char cwd[PATH_MAX];
	char filename[PATH_MAX];
	char url[PATH_MAX];
	FILE *fp = NULL;
	int fd;
	struct aurpkg_t *pkg;

	if (!getcwd(cwd, PATH_MAX)) {
		return error(PW_ERR_GETCWD);
	}

	if (chdir(powaur_dir)) {
		return error(PW_ERR_CHDIR, powaur_dir);
	}

	found = ret = pkgcount = 0;
	for (i = targets; i; i = i->next, ++pkgcount) {
		/* Search sync dbs first */
		spkg = search_syncdbs(syncdbs, i->data);
		if (spkg) {
			if (found++){
				printf("\n");
			}

			pacman_pkgdump(spkg, PKG_FROM_SYNC);
			spkg = NULL;
			continue;
		}

		results = query_aur(curl, i->data, AUR_QUERY_INFO);
		if (alpm_list_count(results) != 1) {
			if (pkgcount > 0) {
				printf("\n");
			}

			pw_printf(PW_LOG_ERROR, "package %s not found\n", i->data);
			goto garbage_collect;
		}

		snprintf(filename, PATH_MAX, "%s.PKGBUILDXXXXXX", i->data);
		fd = mkstemp(filename);

		if (fd < 0) {
			error(PW_ERR_FOPEN, filename);
			goto garbage_collect;
		}

		fp = fdopen(fd, "w+");
		if (!fp) {
			printf("NO\n");
			error(PW_ERR_FOPEN, filename);
			goto garbage_collect;
		}

		snprintf(url, PATH_MAX, AUR_PKGBUILD_URL, i->data);

		/* Download the PKGBUILD and parse it */
		ret = download_single_file(curl, url, fp);
		if (ret) {
			goto destroy_remnants;
		}

		/* Parse PKGBUILD and get detailed info */
		fseek(fp, 0L, SEEK_SET);

		pkg = results->data;
		parse_pkgbuild(pkg, fp);

		if (found++) {
			printf("\n");
		}

		printf("%s%s %saur%s\n", color.bold, REPO, color.bmag, color.nocolor);
		printf("%s%s %s%s\n", color.bold, NAME, pkg->name, color.nocolor);
		printf("%s%s %s%s%s\n", color.bold, VERSION, color.bgreen,
			   pkg->version, color.nocolor);
		printf("%s%s %s%s%s\n", color.bold, URL, color.bcyan, pkg->url,
			   color.nocolor);
		printf("%s%s%s ", color.bold, A_URL, color.bcyan);
		printf(AUR_PKG_URL, pkg->id);
		printf("%s\n", color.nocolor);

		printf("%s%s %s%s\n", color.bold, LICENSES, color.nocolor, pkg->license);
		printf("%s%s %s%d\n", color.bold, A_VOTES, color.nocolor, pkg->votes);
		printf("%s%s ", color.bold, A_OUTOFDATE);
		if (pkg->outofdate) {
			printf("%s%s", color.bred, "Yes");
		} else {
			printf("%s%s", color.nocolor, "No");
		}

		printf("%s\n", color.nocolor);

		print_list_prefix(pkg->provides, PROVIDES);
		print_list_prefix(pkg->depends, DEPS);
		print_list_prefix(pkg->optdepends, OPTDEPS);
		print_list_prefix(pkg->conflicts, CONFLICTS);
		print_list_prefix(pkg->replaces, REPLACES);
		print_list_prefix(pkg->arch, ARCH);

		printf("%s%s%s %s\n", color.bold, DESC, color.nocolor, pkg->desc);

destroy_remnants:
		fclose(fp);
		fp = NULL;
		unlink(filename);

garbage_collect:
		free_list = alpm_list_add(free_list, results);
	}

cleanup:
	for (i = free_list; i; i = i->next) {
		alpm_list_free_inner(i->data, (alpm_list_fn_free) aurpkg_free);
		alpm_list_free(i->data);
	}

	alpm_list_free(free_list);

	if (chdir(cwd)) {
		return error(PW_ERR_RESTORECWD);
	}

	return found ? 0 : -1;
}
Ejemplo n.º 18
0
static int sync_db_populate(alpm_db_t *db)
{
	const char *dbpath;
	size_t est_count;
	int count, fd;
	struct stat buf;
	struct archive *archive;
	struct archive_entry *entry;
	alpm_pkg_t *pkg = NULL;

	if(db->status & DB_STATUS_INVALID) {
		RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1);
	}
	if(db->status & DB_STATUS_MISSING) {
		RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1);
	}
	dbpath = _alpm_db_path(db);
	if(!dbpath) {
		/* pm_errno set in _alpm_db_path() */
		return -1;
	}

	fd = _alpm_open_archive(db->handle, dbpath, &buf,
			&archive, ALPM_ERR_DB_OPEN);
	if(fd < 0) {
		return -1;
	}
	est_count = estimate_package_count(&buf, archive);

	db->pkgcache = _alpm_pkghash_create(est_count);
	if(db->pkgcache == NULL) {
		db->handle->pm_errno = ALPM_ERR_MEMORY;
		count = -1;
		goto cleanup;
	}

	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
		mode_t mode = archive_entry_mode(entry);
		if(S_ISDIR(mode)) {
			continue;
		} else {
			/* we have desc, depends or deltas - parse it */
			if(sync_db_read(db, archive, entry, &pkg) != 0) {
				_alpm_log(db->handle, ALPM_LOG_ERROR,
						_("could not parse package description file '%s' from db '%s'\n"),
						archive_entry_pathname(entry), db->treename);
				continue;
			}
		}
	}

	count = alpm_list_count(db->pkgcache->list);
	if(count > 0) {
		db->pkgcache->list = alpm_list_msort(db->pkgcache->list,
				(size_t)count, _alpm_pkg_cmp);
	}
	_alpm_log(db->handle, ALPM_LOG_DEBUG,
			"added %d packages to package cache for db '%s'\n",
			count, db->treename);

cleanup:
	archive_read_finish(archive);
	if(fd >= 0) {
		CLOSE(fd);
	}
	return count;
}
Ejemplo n.º 19
0
Archivo: deps.c Proyecto: mineo/pacman
/**
 * helper function for resolvedeps: search for dep satisfier in dbs
 *
 * @param handle the context handle
 * @param dep is the dependency to search for
 * @param dbs are the databases to search
 * @param excluding are the packages to exclude from the search
 * @param prompt if true, will cause an unresolvable dependency to issue an
 *        interactive prompt asking whether the package should be removed from
 *        the transaction or the transaction aborted; if false, simply returns
 *        an error code without prompting
 * @return the resolved package
 **/
static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep,
		alpm_list_t *dbs, alpm_list_t *excluding, int prompt)
{
	alpm_list_t *i, *j;
	int ignored = 0;

	alpm_list_t *providers = NULL;
	int count;

	/* 1. literals */
	for(i = dbs; i; i = i->next) {
		pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name);
		if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) {
			if(_alpm_pkg_should_ignore(handle, pkg)) {
				int install = 0;
				if(prompt) {
					QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg,
							 NULL, NULL, &install);
				} else {
					_alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);
				}
				if(!install) {
					ignored = 1;
					continue;
				}
			}
			return pkg;
		}
	}
	/* 2. satisfiers (skip literals here) */
	for(i = dbs; i; i = i->next) {
		for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) {
			pmpkg_t *pkg = j->data;
			if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 &&
			             !_alpm_pkg_find(excluding, pkg->name)) {
				if(_alpm_pkg_should_ignore(handle, pkg)) {
					int install = 0;
					if(prompt) {
						QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG,
									pkg, NULL, NULL, &install);
					} else {
						_alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version);
					}
					if(!install) {
						ignored = 1;
						continue;
					}
				}
				_alpm_log(handle, PM_LOG_DEBUG, "provider found (%s provides %s)\n",
						pkg->name, dep->name);
				providers = alpm_list_add(providers, pkg);
				/* keep looking for other providers in the all dbs */
			}
		}
	}

	/* first check if one provider is already installed locally */
	for(i = providers; i; i = i->next) {
		pmpkg_t *pkg = i->data;
		if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) {
			alpm_list_free(providers);
			return pkg;
		}
	}
	count = alpm_list_count(providers);
	if(count >= 1) {
		/* default to first provider if there is no QUESTION callback */
		int index = 0;
		if(count > 1) {
			/* if there is more than one provider, we ask the user */
			QUESTION(handle->trans, PM_TRANS_CONV_SELECT_PROVIDER,
					providers, dep, NULL, &index);
		}
		if(index >= 0 && index < count) {
			pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index));
			alpm_list_free(providers);
			return pkg;
		}
		alpm_list_free(providers);
		providers = NULL;
	}

	if(ignored) { /* resolvedeps will override these */
		handle->pm_errno = PM_ERR_PKG_IGNORED;
	} else {
		handle->pm_errno = PM_ERR_PKG_NOT_FOUND;
	}
	return NULL;
}
Ejemplo n.º 20
0
/* TODO this is one of the worst ever functions written. void *data ? wtf */
void cb_trans_conv(pmtransconv_t event, void *data1, void *data2,
                   void *data3, int *response)
{
	switch(event) {
		case PM_TRANS_CONV_INSTALL_IGNOREPKG:
			if(!config->op_s_downloadonly) {
				*response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"),
								  alpm_pkg_get_name(data1));
			} else {
				*response = 1;
			}
			break;
		case PM_TRANS_CONV_REPLACE_PKG:
			*response = yesno(_(":: Replace %s with %s/%s?"),
					alpm_pkg_get_name(data1),
					(char *)data3,
					alpm_pkg_get_name(data2));
			break;
		case PM_TRANS_CONV_CONFLICT_PKG:
			/* data parameters: target package, local package, conflict (strings) */
			/* print conflict only if it contains new information */
			if(strcmp(data1, data3) == 0 || strcmp(data2, data3) == 0) {
				*response = noyes(_(":: %s and %s are in conflict. Remove %s?"),
						(char *)data1,
						(char *)data2,
						(char *)data2);
			} else {
				*response = noyes(_(":: %s and %s are in conflict (%s). Remove %s?"),
						(char *)data1,
						(char *)data2,
						(char *)data3,
						(char *)data2);
			}
			break;
		case PM_TRANS_CONV_REMOVE_PKGS:
			{
				alpm_list_t *unresolved = (alpm_list_t *) data1;
				alpm_list_t *namelist = NULL, *i;
				size_t count = 0;
				for (i = unresolved; i; i = i->next) {
					namelist = alpm_list_add(namelist,
							(char *)alpm_pkg_get_name(i->data));
					count++;
				}
				printf(_n(
							":: The following package cannot be upgraded due to unresolvable dependencies:\n",
							":: The following packages cannot be upgraded due to unresolvable dependencies:\n",
							count));
				list_display("     ", namelist);
				printf("\n");
				*response = noyes(_n(
							"Do you want to skip the above package for this upgrade?",
							"Do you want to skip the above packages for this upgrade?",
							count));
				alpm_list_free(namelist);
			}
			break;
		case PM_TRANS_CONV_SELECT_PROVIDER:
			{
				alpm_list_t *providers = (alpm_list_t *)data1;
				int count = alpm_list_count(providers);
				char *depstring = alpm_dep_compute_string((pmdepend_t *)data2);
				printf(_(":: There are %d providers available for %s:\n"), count,
						depstring);
				free(depstring);
				select_display(providers);
				*response = select_question(count);
			}
			break;
		case PM_TRANS_CONV_LOCAL_NEWER:
			if(!config->op_s_downloadonly) {
				*response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"),
						alpm_pkg_get_name(data1),
						alpm_pkg_get_version(data1));
			} else {
				*response = 1;
			}
			break;
		case PM_TRANS_CONV_CORRUPTED_PKG:
			*response = yesno(_(":: File %s is corrupted. Do you want to delete it?"),
					(char *)data1);
			break;
	}
	if(config->noask) {
		if(config->ask & event) {
			/* inverse the default answer */
			*response = !*response;
		}
	}
}
Ejemplo n.º 21
0
/** Display usage/syntax for the specified operation.
 * @param op     the operation code requested
 * @param myname basename(argv[0])
 */
static void usage(int op, const char * const myname)
{
#define addlist(s) (list = alpm_list_add(list, s))
	alpm_list_t *list = NULL, *i;
	/* prefetch some strings for usage below, which moves a lot of calls
	 * out of gettext. */
	char const *const str_opt  = _("options");
	char const *const str_file = _("file(s)");
	char const *const str_pkg  = _("package(s)");
	char const *const str_usg  = _("usage");
	char const *const str_opr  = _("operation");

	/* please limit your strings to 80 characters in width */
	if(op == PM_OP_MAIN) {
		printf("%s:  %s <%s> [...]\n", str_usg, myname, str_opr);
		printf(_("operations:\n"));
		printf("    %s {-h --help}\n", myname);
		printf("    %s {-V --version}\n", myname);
		printf("    %s {-D --database} <%s> <%s>\n", myname, str_opt, str_pkg);
		printf("    %s {-Q --query}    [%s] [%s]\n", myname, str_opt, str_pkg);
		printf("    %s {-R --remove}   [%s] <%s>\n", myname, str_opt, str_pkg);
		printf("    %s {-S --sync}     [%s] [%s]\n", myname, str_opt, str_pkg);
		printf("    %s {-T --deptest}  [%s] [%s]\n", myname, str_opt, str_pkg);
		printf("    %s {-U --upgrade}  [%s] <%s>\n", myname, str_opt, str_file);
		printf(_("\nuse '%s {-h --help}' with an operation for available options\n"),
				myname);
	} else {
		if(op == PM_OP_REMOVE) {
			printf("%s:  %s {-R --remove} [%s] <%s>\n", str_usg, myname, str_opt, str_pkg);
			printf("%s:\n", str_opt);
			addlist(_("  -c, --cascade        remove packages and all packages that depend on them\n"));
			addlist(_("  -n, --nosave         remove configuration files\n"));
			addlist(_("  -s, --recursive      remove unnecessary dependencies\n"
			          "                       (-ss includes explicitly installed dependencies)\n"));
			addlist(_("  -u, --unneeded       remove unneeded packages\n"));
		} else if(op == PM_OP_UPGRADE) {
			printf("%s:  %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file);
			addlist(_("      --needed         do not reinstall up to date packages\n"));
			printf("%s:\n", str_opt);
		} else if(op == PM_OP_QUERY) {
			printf("%s:  %s {-Q --query} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
			printf("%s:\n", str_opt);
			addlist(_("  -c, --changelog      view the changelog of a package\n"));
			addlist(_("  -d, --deps           list packages installed as dependencies [filter]\n"));
			addlist(_("  -e, --explicit       list packages explicitly installed [filter]\n"));
			addlist(_("  -g, --groups         view all members of a package group\n"));
			addlist(_("  -i, --info           view package information (-ii for backup files)\n"));
			addlist(_("  -k, --check          check that package files exist (-kk for file properties)\n"));
			addlist(_("  -l, --list           list the files owned by the queried package\n"));
			addlist(_("  -m, --foreign        list installed packages not found in sync db(s) [filter]\n"));
			addlist(_("  -n, --native         list installed packages only found in sync db(s) [filter]\n"));
			addlist(_("  -o, --owns <file>    query the package that owns <file>\n"));
			addlist(_("  -p, --file <package> query a package file instead of the database\n"));
			addlist(_("  -q, --quiet          show less information for query and search\n"));
			addlist(_("  -s, --search <regex> search locally-installed packages for matching strings\n"));
			addlist(_("  -t, --unrequired     list packages not (optionally) required by any\n"
			          "                       package (-tt to ignore optdepends) [filter]\n"));
			addlist(_("  -u, --upgrades       list outdated packages [filter]\n"));
		} else if(op == PM_OP_SYNC) {
			printf("%s:  %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
			printf("%s:\n", str_opt);
			addlist(_("  -c, --clean          remove old packages from cache directory (-cc for all)\n"));
			addlist(_("  -g, --groups         view all members of a package group\n"
			          "                       (-gg to view all groups and members)\n"));
			addlist(_("  -i, --info           view package information (-ii for extended information)\n"));
			addlist(_("  -l, --list <repo>    view a list of packages in a repo\n"));
			addlist(_("  -q, --quiet          show less information for query and search\n"));
			addlist(_("  -s, --search <regex> search remote repositories for matching strings\n"));
			addlist(_("  -u, --sysupgrade     upgrade installed packages (-uu enables downgrades)\n"));
			addlist(_("  -w, --downloadonly   download packages but do not install/upgrade anything\n"));
			addlist(_("  -y, --refresh        download fresh package databases from the server\n"
			          "                       (-yy to force a refresh even if up to date)\n"));
			addlist(_("      --needed         do not reinstall up to date packages\n"));
		} else if(op == PM_OP_DATABASE) {
			printf("%s:  %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg);
			printf("%s:\n", str_opt);
			addlist(_("      --asdeps         mark packages as non-explicitly installed\n"));
			addlist(_("      --asexplicit     mark packages as explicitly installed\n"));
			addlist(_("  -k, --check          test local database for validity (-kk for sync databases)\n"));
		} else if(op == PM_OP_DEPTEST) {
			printf("%s:  %s {-T --deptest} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
			printf("%s:\n", str_opt);
		}
		switch(op) {
			case PM_OP_SYNC:
			case PM_OP_UPGRADE:
				addlist(_("      --force          force install, overwrite conflicting files\n"));
				addlist(_("      --asdeps         install packages as non-explicitly installed\n"));
				addlist(_("      --asexplicit     install packages as explicitly installed\n"));
				addlist(_("      --ignore <pkg>   ignore a package upgrade (can be used more than once)\n"));
				addlist(_("      --ignoregroup <grp>\n"
				          "                       ignore a group upgrade (can be used more than once)\n"));
				/* pass through */
			case PM_OP_REMOVE:
				addlist(_("  -d, --nodeps         skip dependency version checks (-dd to skip all checks)\n"));
				addlist(_("      --assume-installed <package=version>\n"
				          "                       add a virtual package to satisfy dependencies\n"));
				addlist(_("      --dbonly         only modify database entries, not package files\n"));
				addlist(_("      --noprogressbar  do not show a progress bar when downloading files\n"));
				addlist(_("      --noscriptlet    do not execute the install scriptlet if one exists\n"));
				addlist(_("  -p, --print          print the targets instead of performing the operation\n"));
				addlist(_("      --print-format <string>\n"
				          "                       specify how the targets should be printed\n"));
				break;
		}

		addlist(_("  -b, --dbpath <path>  set an alternate database location\n"));
		addlist(_("  -r, --root <path>    set an alternate installation root\n"));
		addlist(_("  -v, --verbose        be verbose\n"));
		addlist(_("      --arch <arch>    set an alternate architecture\n"));
		addlist(_("      --cachedir <dir> set an alternate package cache location\n"));
		addlist(_("      --color <when>   colorize the output\n"));
		addlist(_("      --config <path>  set an alternate configuration file\n"));
		addlist(_("      --debug          display debug messages\n"));
		addlist(_("      --gpgdir <path>  set an alternate home directory for GnuPG\n"));
		addlist(_("      --logfile <path> set an alternate log file\n"));
		addlist(_("      --noconfirm      do not ask for any confirmation\n"));
		addlist(_("      --confirm        always ask for confirmation\n"));
	}
	list = alpm_list_msort(list, alpm_list_count(list), options_cmp);
	for(i = list; i; i = alpm_list_next(i)) {
		fputs((const char *)i->data, stdout);
	}
	alpm_list_free(list);
#undef addlist
}
Ejemplo n.º 22
0
/* prepare a list of pkgs to display */
static void _display_targets(alpm_list_t *targets, int verbose)
{
	char *str;
	off_t isize = 0, rsize = 0, dlsize = 0;
	unsigned short cols;
	alpm_list_t *i, *names = NULL, *header = NULL, *rows = NULL;

	if(!targets) {
		return;
	}

	/* gather package info */
	for(i = targets; i; i = alpm_list_next(i)) {
		pm_target_t *target = i->data;

		if(target->install) {
			dlsize += alpm_pkg_download_size(target->install);
			isize += alpm_pkg_get_isize(target->install);
		}
		if(target->remove) {
			/* add up size of all removed packages */
			rsize += alpm_pkg_get_isize(target->remove);
		}
	}

	/* form data for both verbose and non-verbose display */
	for(i = targets; i; i = alpm_list_next(i)) {
		pm_target_t *target = i->data;

		if(verbose) {
			rows = alpm_list_add(rows, create_verbose_row(target));
		}

		if(target->install) {
			pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install),
					alpm_pkg_get_version(target->install));
		} else if(isize == 0) {
			pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->remove),
					alpm_pkg_get_version(target->remove));
		} else {
			pm_asprintf(&str, "%s-%s [%s]", alpm_pkg_get_name(target->remove),
					alpm_pkg_get_version(target->remove), _("removal"));
		}
		names = alpm_list_add(names, str);
	}

	/* print to screen */
	pm_asprintf(&str, "%s (%zd)", _("Packages"), alpm_list_count(targets));
	printf("\n");

	cols = getcols(fileno(stdout));
	if(verbose) {
		header = create_verbose_header(alpm_list_count(targets));
		if(table_display(header, rows, cols) != 0) {
			/* fallback to list display if table wouldn't fit */
			list_display(str, names, cols);
		}
	} else {
		list_display(str, names, cols);
	}
	printf("\n");

	table_free(header, rows);
	FREELIST(names);
	free(str);
	rows = NULL;

	if(dlsize > 0 || config->op_s_downloadonly) {
		add_transaction_sizes_row(&rows, _("Total Download Size:"), dlsize);
	}
	if(!config->op_s_downloadonly) {
		if(isize > 0) {
			add_transaction_sizes_row(&rows, _("Total Installed Size:"), isize);
		}
		if(rsize > 0 && isize == 0) {
			add_transaction_sizes_row(&rows, _("Total Removed Size:"), rsize);
		}
		/* only show this net value if different from raw installed size */
		if(isize > 0 && rsize > 0) {
			add_transaction_sizes_row(&rows, _("Net Upgrade Size:"), isize - rsize);
		}
	}
	table_display(NULL, rows, cols);
	table_free(NULL, rows);
}