Exemplo n.º 1
0
Arquivo: expac.c Projeto: aissat/expac
static int read_targets_from_file(FILE *in, alpm_list_t **targets)
{
  char line[BUFSIZ];
  int i = 0, end = 0;
  while(!end) {
    line[i] = fgetc(in);

    if(line[i] == EOF)
      end = 1;

    if(isspace(line[i]) || end) {
      line[i] = '\0';
      /* avoid adding zero length arg, if multiple spaces separate args */
      if(i > 0) {
        if(!alpm_list_find_str(*targets, line))
          *targets = alpm_list_add(*targets, strdup(line));
        i = 0;
      }
    } else {
      ++i;
      if(i >= BUFSIZ) {
        fprintf(stderr, "error: buffer overflow on stdin\n");
        return -1;
      }
    }
  }

  return 0;
}
Exemplo n.º 2
0
static pmpkg_t *
alpm_pkg_find_update (pmpkg_t *pkg, const alpm_list_t *dbs)
{
	const gchar *name;
	const alpm_list_t *i;

	g_return_val_if_fail (pkg != NULL, NULL);

	name = alpm_pkg_get_name (pkg);

	for (; dbs != NULL; dbs = dbs->next) {
		pmpkg_t *update = alpm_db_get_pkg (dbs->data, name);

		if (update != NULL) {
			if (alpm_pkg_vercmp (alpm_pkg_get_version (update),
					     alpm_pkg_get_version (pkg)) > 0) {
				return update;
			} else {
				return NULL;
			}
		}

		i = alpm_db_get_pkgcache (dbs->data);
		for (; i != NULL; i = i->next) {
			if (alpm_list_find_str (alpm_pkg_get_replaces (i->data),
						name) != NULL) {
				return i->data;
			}
		}
	}

	return NULL;
}
Exemplo n.º 3
0
/**
 * walk dependencies, showing dependencies of the target
 */
static void walk_deps(alpm_list_t *dblist, alpm_pkg_t *pkg, tdepth *depth, int rev)
{
	alpm_list_t *deps, *i;

	if(!pkg || ((max_depth >= 0) && (depth->level > max_depth))) {
		return;
	}

	walked = alpm_list_add(walked, (void *)alpm_pkg_get_name(pkg));

	if(rev) {
		deps = alpm_pkg_compute_requiredby(pkg);
	} else {
		deps = get_pkg_dep_names(pkg);
	}

	for(i = deps; i; i = alpm_list_next(i)) {
		const char *pkgname = i->data;
		int last = alpm_list_next(i) ? 0 : 1;

		alpm_pkg_t *dep_pkg = alpm_find_dbs_satisfier(handle, dblist, pkgname);

		if(alpm_list_find_str(walked, dep_pkg ? alpm_pkg_get_name(dep_pkg) : pkgname)) {
			/* if we've already seen this package, don't print in "unique" output
			 * and don't recurse */
			if(!unique) {
				print(alpm_pkg_get_name(pkg), alpm_pkg_get_name(dep_pkg), pkgname, depth, last);
			}
		} else {
			print(alpm_pkg_get_name(pkg), alpm_pkg_get_name(dep_pkg), pkgname, depth, last);
			if(dep_pkg) {
				tdepth d = {
					depth,
					NULL,
					depth->level + 1
				};
				depth->next = &d;
				/* last dep, cut off the limb here */
				if(last) {
					if(depth->prev) {
						depth->prev->next = &d;
						d.prev = depth->prev;
						depth = &d;
					} else {
						d.prev = NULL;
					}
				}
				walk_deps(dblist, dep_pkg, &d, rev);
				depth->next = NULL;
			}
		}
	}

	if(rev) {
		FREELIST(deps);
	} else {
		alpm_list_free(deps);
	}
}
Exemplo n.º 4
0
static gboolean
alpm_pkg_is_syncfirst (pmpkg_t *pkg)
{
	g_return_val_if_fail (pkg != NULL, FALSE);

	if (alpm_list_find_str (syncfirsts, alpm_pkg_get_name (pkg)) != NULL) {
		return TRUE;
	}

	return FALSE;
}
Exemplo n.º 5
0
static gboolean
alpm_pkg_is_ignorepkg (pmpkg_t *pkg)
{
	const alpm_list_t *ignorepkgs, *ignoregrps, *i;

	g_return_val_if_fail (pkg != NULL, TRUE);

	ignorepkgs = alpm_option_get_ignorepkgs ();
	if (alpm_list_find_str (ignorepkgs, alpm_pkg_get_name (pkg)) != NULL) {
		return TRUE;
	}

	ignoregrps = alpm_option_get_ignoregrps ();
	for (i = alpm_pkg_get_groups (pkg); i != NULL; i = i->next) {
		if (alpm_list_find_str (ignoregrps, i->data) != NULL) {
			return TRUE;
		}
	}

	return FALSE;
}
Exemplo n.º 6
0
static void print_graph(const char *parentname, const char *pkgname, const char *depname)
{
	if(depname) {
		printf("\"%s\" -> \"%s\" [color=chocolate4];\n", parentname, depname);
		if(pkgname && strcmp(depname, pkgname) != 0 && !alpm_list_find_str(provisions, depname)) {
			printf("\"%s\" -> \"%s\" [arrowhead=none, color=grey];\n", depname, pkgname);
			provisions = alpm_list_add(provisions, (char *)depname);
		}
	} else if(pkgname) {
		printf("\"%s\" -> \"%s\" [color=chocolate4];\n", parentname, pkgname);
	}
}
Exemplo n.º 7
0
static gboolean
pk_alpm_transaction_remove_simulate (PkBackendJob *job, GError **error)
{
	PkBackend *backend = pk_backend_job_get_backend (job);
	PkBackendAlpmPrivate *priv = pk_backend_get_user_data (backend);
	const alpm_list_t *i;

	if (!pk_alpm_transaction_simulate (job, error))
		return FALSE;

	for (i = alpm_trans_get_remove (priv->alpm); i != NULL; i = i->next) {
		const gchar *name = alpm_pkg_get_name (i->data);
		if (alpm_list_find_str (priv->holdpkgs, name)) {
			g_set_error (error, PK_ALPM_ERROR, PK_ALPM_ERR_PKG_HELD,
				     "%s: %s", name,
				     "could not remove HoldPkg");
			return FALSE;
		}
	}

	return TRUE;
}
Exemplo n.º 8
0
/** Main function.
 * @param argc
 * @param argv
 * @return A return code indicating success, failure, etc.
 */
int main(int argc, char *argv[])
{
	int ret = 0;
	size_t i;
	struct sigaction new_action, old_action;
	const int signals[] = { SIGHUP, SIGINT, SIGTERM, SIGSEGV, SIGWINCH };
	uid_t myuid = getuid();

	/* Set signal handlers */
	/* Set up the structure to specify the new action. */
	new_action.sa_handler = handler;
	sigemptyset(&new_action.sa_mask);
	new_action.sa_flags = SA_RESTART;

	/* assign our handler to any signals we care about */
	for(i = 0; i < sizeof(signals) / sizeof(signals[0]); i++) {
		int signal = signals[i];
		sigaction(signal, NULL, &old_action);
		if(old_action.sa_handler != SIG_IGN) {
			sigaction(signal, &new_action, NULL);
		}
	}

	/* i18n init */
#if defined(ENABLE_NLS)
	localize();
#endif

	/* set user agent for downloading */
	setuseragent();

	/* init config data */
	if(!(config = config_new())) {
		/* config_new prints the appropriate error message */
		cleanup(1);
	}

	/* disable progressbar if the output is redirected */
	if(!isatty(fileno(stdout))) {
		config->noprogressbar = 1;
	}

	/* Priority of options:
	 * 1. command line
	 * 2. config file
	 * 3. compiled-in defaults
	 * However, we have to parse the command line first because a config file
	 * location can be specified here, so we need to make sure we prefer these
	 * options over the config file coming second.
	 */

	/* parse the command line */
	ret = parseargs(argc, argv);
	if(ret != 0) {
		cleanup(ret);
	}

	/* we support reading targets from stdin if a cmdline parameter is '-' */
	if(alpm_list_find_str(pm_targets, "-")) {
		if(!isatty(fileno(stdin))) {
			int target_found = 0;
			size_t current_size = PATH_MAX;
			char *vdata, *line = malloc(current_size);
			int c;

			/* remove the '-' from the list */
			pm_targets = alpm_list_remove_str(pm_targets, "-", &vdata);
			free(vdata);

			i = 0;
			do {
				c = fgetc(stdin);
				if(c == EOF || isspace(c)) {
					/* avoid adding zero length arg when multiple spaces separate args */
					if(i > 0) {
						line[i] = '\0';
						pm_targets = alpm_list_add(pm_targets, strdup(line));
						target_found = 1;
						i = 0;
					}
				} else {
					line[i++] = (char)c;
					/* we may be at the end of our allocated buffer now */
					if(i >= current_size) {
						char *new = realloc(line, current_size * 2);
						if(new) {
							line = new;
							current_size *= 2;
						} else {
							free(line);
							pm_printf(ALPM_LOG_ERROR,
									_("memory exhausted in argument parsing\n"));
							cleanup(EXIT_FAILURE);
						}
					}
				}
			} while(c != EOF);
Exemplo n.º 9
0
/** Search for packages to upgrade and add them to the transaction. */
int SYMEXPORT alpm_sync_sysupgrade(alpm_handle_t *handle, int enable_downgrade)
{
	alpm_list_t *i, *j, *k;
	alpm_trans_t *trans;
	alpm_db_t *db_local;
	alpm_list_t *dbs_sync;

	CHECK_HANDLE(handle, return -1);
	trans = handle->trans;
	db_local = handle->db_local;
	dbs_sync = handle->dbs_sync;
	ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1));
	ASSERT(trans->state == STATE_INITIALIZED, RET_ERR(handle, ALPM_ERR_TRANS_NOT_INITIALIZED, -1));

	_alpm_log(handle, ALPM_LOG_DEBUG, "checking for package upgrades\n");
	for(i = _alpm_db_get_pkgcache(db_local); i; i = i->next) {
		alpm_pkg_t *lpkg = i->data;

		if(_alpm_pkg_find(trans->add, lpkg->name)) {
			_alpm_log(handle, ALPM_LOG_DEBUG, "%s is already in the target list -- skipping\n", lpkg->name);
			continue;
		}

		/* Search for literal then replacers in each sync database.
		 * If found, don't check other databases */
		for(j = dbs_sync; j; j = j->next) {
			alpm_db_t *sdb = j->data;
			/* Check sdb */
			alpm_pkg_t *spkg = _alpm_db_get_pkgfromcache(sdb, lpkg->name);
			if(spkg) {
				/* 1. literal was found in sdb */
				int cmp = _alpm_pkg_compare_versions(spkg, lpkg);
				if(cmp > 0) {
					_alpm_log(handle, ALPM_LOG_DEBUG, "new version of '%s' found (%s => %s)\n",
								lpkg->name, lpkg->version, spkg->version);
					/* check IgnorePkg/IgnoreGroup */
					if(_alpm_pkg_should_ignore(handle, spkg)
							|| _alpm_pkg_should_ignore(handle, lpkg)) {
						_alpm_log(handle, ALPM_LOG_WARNING, _("%s: ignoring package upgrade (%s => %s)\n"),
								lpkg->name, lpkg->version, spkg->version);
					} else {
						_alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
												spkg->name, spkg->version);
						trans->add = alpm_list_add(trans->add, spkg);
					}
				} else if(cmp < 0) {
					if(enable_downgrade) {
						/* check IgnorePkg/IgnoreGroup */
						if(_alpm_pkg_should_ignore(handle, spkg)
								|| _alpm_pkg_should_ignore(handle, lpkg)) {
							_alpm_log(handle, ALPM_LOG_WARNING, _("%s: ignoring package downgrade (%s => %s)\n"),
											lpkg->name, lpkg->version, spkg->version);
						} else {
							_alpm_log(handle, ALPM_LOG_WARNING, _("%s: downgrading from version %s to version %s\n"),
											lpkg->name, lpkg->version, spkg->version);
							trans->add = alpm_list_add(trans->add, spkg);
						}
					} else {
						_alpm_log(handle, ALPM_LOG_WARNING, _("%s: local (%s) is newer than %s (%s)\n"),
								lpkg->name, lpkg->version, sdb->treename, spkg->version);
					}
				}
				/* jump to next local package */
				break;
			} else {
				/* 2. search for replacers in sdb */
				int found = 0;
				for(k = _alpm_db_get_pkgcache(sdb); k; k = k->next) {
					spkg = k->data;
					if(alpm_list_find_str(alpm_pkg_get_replaces(spkg), lpkg->name)) {
						found = 1;
						/* check IgnorePkg/IgnoreGroup */
						if(_alpm_pkg_should_ignore(handle, spkg)
								|| _alpm_pkg_should_ignore(handle, lpkg)) {
							_alpm_log(handle, ALPM_LOG_WARNING, _("ignoring package replacement (%s-%s => %s-%s)\n"),
										lpkg->name, lpkg->version, spkg->name, spkg->version);
							continue;
						}

						int doreplace = 0;
						QUESTION(trans, ALPM_TRANS_CONV_REPLACE_PKG, lpkg, spkg, sdb->treename, &doreplace);
						if(!doreplace) {
							continue;
						}

						/* If spkg is already in the target list, we append lpkg to spkg's
						 * removes list */
						alpm_pkg_t *tpkg = _alpm_pkg_find(trans->add, spkg->name);
						if(tpkg) {
							/* sanity check, multiple repos can contain spkg->name */
							if(tpkg->origin_data.db != sdb) {
								_alpm_log(handle, ALPM_LOG_WARNING, _("cannot replace %s by %s\n"),
													lpkg->name, spkg->name);
								continue;
							}
							_alpm_log(handle, ALPM_LOG_DEBUG, "appending %s to the removes list of %s\n",
												lpkg->name, tpkg->name);
							tpkg->removes = alpm_list_add(tpkg->removes, lpkg);
							/* check the to-be-replaced package's reason field */
							if(alpm_pkg_get_reason(lpkg) == ALPM_PKG_REASON_EXPLICIT) {
								tpkg->reason = ALPM_PKG_REASON_EXPLICIT;
							}
						} else {
							/* add spkg to the target list */
							/* copy over reason */
							spkg->reason = alpm_pkg_get_reason(lpkg);
							spkg->removes = alpm_list_add(NULL, lpkg);
							_alpm_log(handle, ALPM_LOG_DEBUG, "adding package %s-%s to the transaction targets\n",
													spkg->name, spkg->version);
							trans->add = alpm_list_add(trans->add, spkg);
						}
					}
				}
				if(found) {
					break; /* jump to next local package */
				}
			}
		}
	}

	return 0;
}
Exemplo n.º 10
0
/**
 * pacman_list_find_string:
 * @haystack: A #PacmanList.
 * @needle: A string to find.
 *
 * Searches @haystack for a string equal to @needle.
 *
 * Returns: A string from @haystack, or %NULL if none were found.
 */
gchar *pacman_list_find_string (const PacmanList *haystack, const gchar *needle) {
	return alpm_list_find_str (haystack, needle);
}
Exemplo n.º 11
0
int main (int argc, char **argv)
{
	int ret=0, i;
	int need=0, given=0, cycle_db=0, db_order=0;
	alpm_list_t *t;

	struct sigaction a;
	init_config (argv[0]);
	a.sa_handler = handler;
	sigemptyset(&a.sa_mask);
	a.sa_flags = 0;
	sigaction(SIGINT, &a, NULL);
	sigaction(SIGTERM, &a, NULL);

	int opt;
	int opt_index=0;
	static struct option opts[] =
	{
		{"query",      no_argument,       0, 'Q'},
		{"sync",       no_argument,       0, 'S'},
		{"dbpath",     required_argument, 0, 'b'},
		{"deps",       no_argument,       0, 'd'},
		{"explicit",   no_argument,       0, 'e'},
		{"groups",     no_argument,       0, 'g'},
		{"help",       no_argument,       0, 'h'},
		{"info",       no_argument,       0, 'i'},
		{"list",       no_argument,       0, 'l'},
		{"foreign",    no_argument,       0, 'm'},
		{"file",       no_argument,       0, 'p'},
		{"quiet",      no_argument,       0, 'q'},
		{"root",       required_argument, 0, 'r'},
		{"search",     no_argument,       0, 's'},
		{"unrequired", no_argument,       0, 't'},
		{"upgrades",   no_argument,       0, 'u'},
		{"config",     required_argument, 0, 'c'},
		{"just-one",   no_argument,       0, '1'},
		{"aur",        no_argument,       0, 'A'},
		{"escape",     no_argument,       0, 'x'},
		{"format",     required_argument, 0, 'f'},
		{"list-repo",  required_argument, 0, 'L'},
		{"query-type", required_argument, 0, 1000},
		{"csep",       required_argument, 0, 1001},
		{"delimiter",  required_argument, 0, 1001},
		{"sort",       required_argument, 0, 1002},
		{"nocolor",    no_argument,       0, 1003},
		{"number",     no_argument,       0, 1004},
		{"get-res",    no_argument,       0, 1005},
		{"show-size",  no_argument,       0, 1006},
		{"aur-url",    required_argument, 0, 1007},
		{"insecure",   no_argument,       0, 1008},
		{"qdepends",   no_argument,       0, 1009},
		{"qconflicts", no_argument,       0, 1010},
		{"qprovides",  no_argument,       0, 1011},
		{"qreplaces",  no_argument,       0, 1012},
		{"qrequires",  no_argument,       0, 1013},
		{"color",      no_argument,       0, 1014},
		{"version",    no_argument,       0, 'v'},

		{0, 0, 0, 0}
	};

	
	while ((opt = getopt_long (argc, argv, "1Ac:b:def:ghiLlmpQqr:Sstuvx", opts, &opt_index)) != -1) 
	{
		switch (opt) 
		{
			case '1':
				config.just_one = 1;
				break;
			case 'A':
				if (config.aur) break;
				config.aur = ++db_order;
				given |= N_DB;
				break;
			case 'c':
				FREE (config.configfile);
				config.configfile = strndup (optarg, PATH_MAX);
				break;
			case 'b':
				FREE (config.dbpath);
				config.dbpath = strndup (optarg, PATH_MAX);
				break;
			case 'd':
				config.filter |= F_DEPS;
				break;
			case 'e':
				config.filter |= F_EXPLICIT;
				break;
			case 'x':
				config.escape = 1;
				break;
			case 'f':
				config.custom_out = 1;
				strncpy (config.format_out, optarg, PATH_MAX);
				format_str (config.format_out);
				break;
			case 'g':
				if (config.op) break;
				config.op = OP_LIST_GROUP;
				config.filter |= F_GROUP;
				cycle_db = 1;
				break;
			case 'i':
				if (config.op)
				{
					if (config.op == OP_INFO) config.op = OP_INFO_P;
					break;
				}
				config.op = OP_INFO;
				need |= N_TARGET | N_DB;
				break;
			case 'L':
				config.list = 1;
				break;
			case 'l':
				if (config.op) break;
				config.op = OP_LIST_REPO;
				need |= N_DB;
				cycle_db = 1;
				break;
			case 'm':
				config.filter |= F_FOREIGN;
				break;
			case 'p':
				config.is_file = 1;
				need |= N_TARGET;
				break;
			case 'Q':
				if (config.db_local) break;
				config.db_local = ++db_order;
				given |= N_DB;
				break;
			case 'q':
				config.quiet = 1;
				break;
			case 'r':
				FREE (config.rootdir);
				config.rootdir = strndup (optarg, PATH_MAX);
				break;
			case 's':
				if (config.op) break;
				config.op = OP_SEARCH;
				need |= N_DB;
				cycle_db = 1;
				break;
			case 'S':
				if (config.db_sync) break;
				config.db_sync = ++db_order;
				given |= N_DB;
				break;
			case 't':
				config.filter |= F_UNREQUIRED;
				break;
			case 1000: /* --query-type */
				if (config.op) break;
				config.op = OP_QUERY;
				if (strcmp (optarg, "depends")==0)
					config.query = OP_Q_DEPENDS;
				else if (strcmp (optarg, "conflicts")==0)
					config.query = OP_Q_CONFLICTS;
				else if (strcmp (optarg, "provides")==0)
					config.query = OP_Q_PROVIDES;
				else if (strcmp (optarg, "replaces")==0)
					config.query = OP_Q_REPLACES;
				need |= N_TARGET | N_DB;
				break;
			case 1009: /* --qdepends */
				SETQUERY (OP_Q_DEPENDS); break;
			case 1010: /* --qconflicts */
				SETQUERY (OP_Q_CONFLICTS); break;
			case 1011: /* --qprovides */
				SETQUERY (OP_Q_PROVIDES); break;
			case 1012: /* --qreplaces */
				SETQUERY (OP_Q_REPLACES); break;
			case 1013: /* --qrequires */
				SETQUERY (OP_Q_REQUIRES); break;
			case 1001: /* --delimiter */
				strncpy (config.delimiter, optarg, SEP_LEN);
				format_str (config.delimiter);
				break;
			case 1002: /* --sort */
				config.sort = optarg[0];
				break;
			case 1003: /* --nocolor */
				config.colors=0;
				break;
			case 1004: /* --number */
				config.numbering = 1;
				break;
			case 1005: /* --get-res */
				if (dup2(FD_RES, FD_RES) == FD_RES)
					config.get_res = 1;
				break;
			case 1006: /* --show-size */
				config.show_size = 1;
				break;
			case 1007: /* --aur-url */
				FREE (config.aur_url);
				config.aur_url = strdup (optarg);
				break;
			case 1008: /* --insecure */
				config.insecure = 1;
				break;
			case 1014: /* --color */
				config.colors=1;
				break;
			case 'u':
				config.filter |= F_UPGRADES;
				break;
			case 'v':
				version(); break;
			case 'h': usage (0); break;
			default: /* '?' */
				usage (1);
		}
	}
	if (config.list)
	{
		/* -L displays respository list and exits. */
		alpm_list_t *dbs = get_db_sync ();
		if (dbs)
		{
			for(t = dbs; t; t = alpm_list_next(t))
				printf ("%s\n", (char *)t->data);
			FREELIST (dbs);
		}
		cleanup (0);
	}
	if (!config.custom_out)
	{
		if (config.colors)
			color_init();
#if defined(HAVE_GETTEXT) && defined(ENABLE_NLS)
		/* TODO: specific package-query locale ? */
		setlocale (LC_ALL, "");
		bindtextdomain ("yaourt", LOCALEDIR);
		textdomain ("yaourt");
#endif
	}
	if ((need & N_DB) && !(given & N_DB))
	{
		fprintf(stderr, "search or information must have database target (-{Q,S,A}).\n");
		exit(1);
	}
	for (i = optind; i < argc; i++)
	{
		if (!config.just_one ||
		    !alpm_list_find_str (targets, argv[i]))
			targets = alpm_list_add(targets, strdup(argv[i]));
	}
	if (i!=optind) 
	{
		given |= N_TARGET;
	}
	if ((need & N_TARGET) && !(given & N_TARGET))
	{
		fprintf(stderr, "no targets specified.\n");
		usage(1);
	}
	if (targets == NULL)
	{
		if (config.op == OP_SEARCH)	config.op = OP_LIST_REPO_S;
	}
	else if (!config.op && (given & N_DB)) /* Show info by default */
		config.op = OP_INFO;
	// init_db_sync initializes alpm after parsing [options]
	if (!init_db_sync ()) cleanup(1);
	if (config.is_file)
	{
		for(t = targets; t; t = alpm_list_next(t))
		{
			alpm_pkg_t *pkg=NULL;
			const char *filename = t->data;
			if (alpm_pkg_load (config.handle, filename, 0, ALPM_SIG_USE_DEFAULT, &pkg)!=0 || pkg==NULL)
			{
				fprintf(stderr, "unable to read %s.\n", filename);
				continue;
			}
			print_package (filename, pkg, alpm_pkg_get_str);
			ret++;
		}
		cleanup(!ret);
	}

	if  (cycle_db || targets)
	{
		for (i=1; i<=db_order && (cycle_db || targets); i++)
		{
			/*printf ("%d, aur %d, local %d, sync %d\n", i, config.aur, config.db_local, config.db_sync);*/
			if (config.db_sync == i)
			{
				for(t = alpm_get_syncdbs(config.handle); t; t = alpm_list_next(t))
					ret += deal_db (t->data);
				if (!ret && config.op == OP_INFO_P)
				{
					config.op = OP_QUERY;
					config.query = OP_Q_PROVIDES;
					for(t = alpm_get_syncdbs(config.handle); t; t = alpm_list_next(t))
						ret += deal_db (t->data);
					config.op = OP_INFO_P;
				}
			}
			else if (config.db_local == i)
				ret += deal_db (alpm_get_localdb(config.handle));
			else if (config.aur == i)
				switch (config.op)
				{
					case OP_INFO:
					case OP_INFO_P: ret += aur_info (&targets); break;
					case OP_SEARCH: ret += aur_search (targets); break;
					default: break;
				}
		}
	}
	else if (!config.aur && config.db_local)
		ret += alpm_search_local (config.filter, NULL, NULL);
	else if (config.aur && !(given & N_TARGET))
	{
		if (config.filter & F_FOREIGN)
		{
			/* -Am */
			config.aur_foreign = 1;
			config.just_one = 1;
			alpm_search_local (config.filter, "%n", &targets);
			ret += aur_info (&targets);
			if (config.db_local)
				/* -AQm */
				ret += search_pkg_by_name (alpm_get_localdb(config.handle), &targets);
		}
		else if (config.filter & F_UPGRADES)
		{
			/* -Au */
			config.aur_upgrades = 1;
			if (config.db_local)
				/* -AQu */
				ret += alpm_search_local (config.filter, NULL, NULL);
			alpm_search_local (F_FOREIGN | (config.filter & ~F_UPGRADES), "%n>%v", &targets);
			ret += aur_info (&targets);
		}
	}

	show_results();

	/* Some cleanups */
	cleanup(!ret);
	return 0;
}
Exemplo n.º 12
0
/** Unpack a list of files in an archive.
 * @param handle the context handle
 * @param path the archive to unpack
 * @param prefix where to extract the files
 * @param list a list of files within the archive to unpack or NULL for all
 * @param breakfirst break after the first entry found
 * @return 0 on success, 1 on failure
 */
int _alpm_unpack(alpm_handle_t *handle, const char *path, const char *prefix,
		alpm_list_t *list, int breakfirst)
{
	int ret = 0;
	mode_t oldmask;
	struct archive *archive;
	struct archive_entry *entry;
	struct stat buf;
	int fd, cwdfd;

	fd = _alpm_open_archive(handle, path, &buf, &archive, ALPM_ERR_PKG_OPEN);
	if(fd < 0) {
		return 1;
	}

	oldmask = umask(0022);

	/* save the cwd so we can restore it later */
	OPEN(cwdfd, ".", O_RDONLY);
	if(cwdfd < 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not get current working directory\n"));
	}

	/* just in case our cwd was removed in the upgrade operation */
	if(chdir(prefix) != 0) {
		_alpm_log(handle, ALPM_LOG_ERROR, _("could not change directory to %s (%s)\n"),
				prefix, strerror(errno));
		ret = 1;
		goto cleanup;
	}

	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
		const char *entryname;
		mode_t mode;

		entryname = archive_entry_pathname(entry);

		/* If specific files were requested, skip entries that don't match. */
		if(list) {
			char *entry_prefix = strdup(entryname);
			char *p = strstr(entry_prefix,"/");
			if(p) {
				*(p+1) = '\0';
			}
			char *found = alpm_list_find_str(list, entry_prefix);
			free(entry_prefix);
			if(!found) {
				if(archive_read_data_skip(archive) != ARCHIVE_OK) {
					ret = 1;
					goto cleanup;
				}
				continue;
			} else {
				_alpm_log(handle, ALPM_LOG_DEBUG, "extracting: %s\n", entryname);
			}
		}

		mode = archive_entry_mode(entry);
		if(S_ISREG(mode)) {
			archive_entry_set_perm(entry, 0644);
		} else if(S_ISDIR(mode)) {
			archive_entry_set_perm(entry, 0755);
		}

		/* Extract the archive entry. */
		int readret = archive_read_extract(archive, entry, 0);
		if(readret == ARCHIVE_WARN) {
			/* operation succeeded but a non-critical error was encountered */
			_alpm_log(handle, ALPM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
					entryname, archive_error_string(archive));
		} else if(readret != ARCHIVE_OK) {
			_alpm_log(handle, ALPM_LOG_ERROR, _("could not extract %s (%s)\n"),
					entryname, archive_error_string(archive));
			ret = 1;
			goto cleanup;
		}

		if(breakfirst) {
			break;
		}
	}

cleanup:
	umask(oldmask);
	archive_read_finish(archive);
	CLOSE(fd);
	if(cwdfd >= 0) {
		if(fchdir(cwdfd) != 0) {
			_alpm_log(handle, ALPM_LOG_ERROR,
					_("could not restore working directory (%s)\n"), strerror(errno));
		}
		CLOSE(cwdfd);
	}

	return ret;
}
Exemplo n.º 13
0
alpm_list_t *resolve_dependencies(struct pw_hashdb *hashdb, alpm_list_t *packages)
{
	alpm_list_t *i, *k, *m, *q;
	alpm_list_t *deps, *newdeps;

	pmpkg_t *pkg;
	struct pkgpair pkgpair;
	struct pkgpair *pkgpair_ptr;
	char pkgbuild[PATH_MAX];
	struct stat st;

	newdeps = NULL;
	for (i = packages; i; i = i->next) {
		snprintf(pkgbuild, PATH_MAX, "%s/PKGBUILD", i->data);
		/* Grab the list of new dependencies from PKGBUILD */
		deps = grab_dependencies(pkgbuild);
		if (!deps) {
			continue;
		}

		if (config->verbose) {
			printf("\nResolving dependencies for %s\n", i->data);
		}

		for (k = deps; k; k = k->next) {
			pkgpair.pkgname = k->data;

			/* Check against newdeps */
			if (alpm_list_find_str(newdeps, k->data)) {
				continue;
			}

			/* Check against localdb */
			if (hash_search(hashdb->local, &pkgpair)) {
				if (config->verbose) {
					printf("%s%s - Already installed\n", TAB, k->data);
				}

				continue;
			}

			/* Check against sync dbs */
			pkgpair_ptr = hash_search(hashdb->sync, &pkgpair);
			if (pkgpair_ptr) {
				if (config->verbose) {
					printf("%s%s can be found in %s repo\n", TAB, k->data,
						   alpm_db_get_name(alpm_pkg_get_db(pkgpair_ptr->pkg)));
				}

				continue;
			}

			/* Check against provides */
			pkgpair_ptr = hashbst_tree_search(hashdb->local_provides, k->data,
											  hashdb->local, provides_search);
			if (pkgpair_ptr) {
				if (config->verbose) {
					printf("%s%s is provided by %s\n", TAB, k->data, pkgpair_ptr->pkgname);
				}
				continue;
			}

			pkgpair_ptr = hashbst_tree_search(hashdb->sync_provides, k->data,
											  hashdb->sync, provides_search);
			if (pkgpair_ptr) {
				if (config->verbose) {
					printf("%s%s is provided by %s\n", TAB, k->data, pkgpair_ptr->pkgname);
				}
				continue;
			}

			/* Check the directory for pkg/PKGBUILD */
			snprintf(pkgbuild, PATH_MAX, "%s/PKGBUILD", k->data);
			if (!stat(pkgbuild, &st)) {
				if (config->verbose) {
					printf("%s%s has been downloaded\n", TAB, k->data);
				}

				continue;
			}

			/* Add to newdeps */
			newdeps = alpm_list_add(newdeps, strdup(k->data));
			if (config->verbose) {
				printf("%s%s will be downloaded from the AUR\n", TAB, k->data);
			}
		}

		/* Free deps */
		FREELIST(deps);
	}

	return newdeps;
}
Exemplo 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);
}