Esempio n. 1
0
/* -M (--maintainer) search. */
int powaur_maint(alpm_list_t *targets)
{
	if (!targets) {
		pw_printf(PW_LOG_ERROR, "argument needed for -M\n");
		return -1;
	} else if (alpm_list_count(targets) > 1) {
		pw_printf(PW_LOG_ERROR, "-M only takes 1 argument\n");
		return -1;
	}

	int ret;
	size_t listsz;
	alpm_list_t *i, *results;
	struct aurpkg_t *pkg;
	CURL *curl;

	curl = curl_easy_new();
	if (!curl) {
		return error(PW_ERR_CURL_INIT);
	}

	/* Clear pwerrno */
	CLEAR_ERRNO();
	results = query_aur(curl, targets->data, AUR_QUERY_MSEARCH);

	if (pwerrno != PW_ERR_OK) {
		ret = -1;
		goto cleanup;
	} else if (!results) {
		printf("No packages found.\n");
		ret = -1;
		goto cleanup;
	}

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

	if (config->sort_votes) {
		results = alpm_list_msort(results, listsz, aurpkg_vote_cmp);
	}

	for (i = results; i; i = i->next) {
		pkg = 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.byellow, pkg->votes, color.nocolor);
		printf("%s%s\n", TAB, pkg->desc);
	}

cleanup:
	alpm_list_free_inner(results, (alpm_list_fn_free) aurpkg_free);
	alpm_list_free(results);
	curl_easy_cleanup(curl);

	return 0;
}
Esempio n. 2
0
/* Generates the list of packages we are going to install from the AUR, in
 * topological order.
 *
 * @param hashdb hash database
 * @param graph graph of package strings
 * @param topost stack containing topological order of packages
 */
static alpm_list_t *topo_get_targets(struct pw_hashdb *hashdb, struct graph *graph,
									 struct stack *topost)
{
	int curVertex, cnt = 0;
	const char *pkgname;
	enum pkgfrom_t *from = NULL;
	struct pkgpair pkgpair;
	alpm_list_t *final_targets = NULL;

	pw_printf(PW_LOG_VDEBUG, "\n%sDependency graph:\n%s", color.bold, color.nocolor);
	while (!stack_empty(topost)) {
		stack_pop(topost, &curVertex);
		pkgname = graph_get_vertex_data(graph, curVertex);
		from = hashmap_search(hashdb->pkg_from, (void *) pkgname);

		if (!from) {
			alpm_list_free(final_targets);
			return NULL;
		}

		if (cnt++) {
			pw_printf(PW_LOG_VDEBUG, " -> ");
		}
		switch (*from) {
		case PKG_FROM_LOCAL:
			pw_printf(PW_LOG_VDEBUG, "%s%s (installed)%s", color.bgreen, pkgname,
					  color.nocolor);
			break;
		case PKG_FROM_SYNC:
			pw_printf(PW_LOG_VDEBUG, "%s%s (found in sync)%s", color.bblue, pkgname,
					  color.nocolor);
			break;
		case PKG_FROM_AUR:
			/* Magic happens here */
			if (hash_search(hashdb->aur_outdated, (void *) pkgname)) {
				pw_printf(PW_LOG_VDEBUG, "%s%s (AUR target)%s",
						  color.bred, pkgname, color.nocolor);
				final_targets = alpm_list_add(final_targets, (void *) pkgname);
			} else {
				pkgpair.pkgname = pkgname;
				if (hash_search(hashdb->aur, &pkgpair)) {
					pw_printf(PW_LOG_VDEBUG, "%s%s (installed AUR)%s", color.bblue,
							  pkgname, color.nocolor);
				} else {
					/* New AUR package */
					pw_printf(PW_LOG_VDEBUG, "%s%s (AUR dep)%s", color.bmag, pkgname,
							  color.nocolor);
					final_targets = alpm_list_add(final_targets, (void *) pkgname);
				}
			}
			break;
		}
	}

	pw_printf(PW_LOG_VDEBUG, "\n");
	print_immediate_deps(hashdb);
	return final_targets;
}
Esempio n. 3
0
/* Prints list of char *, one on each line with proper indentation */
void indent_print(enum pwloglevel_t lvl, alpm_list_t *list, size_t indent)
{
	alpm_list_t *i;
	int k;
	size_t prefix_len = 0;

	switch (lvl) {
	case PW_LOG_NORM:
		prefix_len = 0;
		break;
	case PW_LOG_INFO:
		prefix_len = 4;
		break;
	case PW_LOG_WARNING:
		prefix_len = 9;
		break;
	case PW_LOG_ERROR:
		prefix_len = 7;
		break;
	case PW_LOG_DEBUG:
		prefix_len = 7;
		break;
	}

	indent += prefix_len;
	for (i = list; i; i = i->next) {
		pw_printf(lvl, "%*s%s\n", indent, "", i->data);
	}
}
Esempio n. 4
0
File: conf.c Progetto: rctay/powaur
static void parse_pmoption_keyval(int *flag, int *flag_com, char *line,
								  const char *key, char **env_conf, int comment)
{
	static const char *keyval_sep = "=";

	if ((comment && (*flag || *flag_com)) || (!comment && *flag)) {
		return;
	}

	strsep(&line, keyval_sep);
	line = strtrim(line);

	if (!strlen(line)) {
		return;
	}

	/* Set global */
	if (*env_conf) {
		free(*env_conf);
	}

	*env_conf = strdup(line);
	pw_printf(PW_LOG_DEBUG, "%s%sDefault %s = %s\n",
			  comstrs.tab, comstrs.tab, key, *env_conf);

	if (comment) {
		*flag_com = 1;
	} else {
		*flag = 1;
	}
}
Esempio n. 5
0
/* Obtain deps, optional deps, conflicts, replaces from fp */
void parse_pkgbuild(struct aurpkg_t *pkg, FILE *fp)
{
	char buf[PATH_MAX];
	char *line;

	char *token;
	char *saveptr;

	while (line = fgets(buf, PATH_MAX, fp)) {
		line = strtrim(line);

		if (line == NULL || strlen(line) == 0) {
			continue;
		}

		if (!strncmp(line, "depends", 7)) {
			pw_printf(PW_LOG_DEBUG, "Parsing PKGBUILD depends\n");

			PARSE_BASH_ARRAY_PREAMBLE(line);
			parse_bash_array(&(pkg->depends), fp, buf, line, 1);

		} else if (!strncmp(line, "provides", 8)) {
			pw_printf(PW_LOG_DEBUG, "Parsing PKGBUILD provides\n");

			PARSE_BASH_ARRAY_PREAMBLE(line);
			parse_bash_array(&(pkg->provides), fp, buf, line, 1);

		} else if (!strncmp(line, "conflicts", 9)) {
			pw_printf(PW_LOG_DEBUG, "Parsing PKGBUILD conflicts\n");

			PARSE_BASH_ARRAY_PREAMBLE(line);
			parse_bash_array(&(pkg->conflicts), fp, buf, line, 1);
		} else if (!strncmp(line, "replaces", 8)) {
			pw_printf(PW_LOG_DEBUG, "Parsing PKGBUILD replaces\n");

			PARSE_BASH_ARRAY_PREAMBLE(line);
			parse_bash_array(&(pkg->replaces), fp, buf, line, 1);
		} else if (!strncmp(line, "arch", 4)) {
			pw_printf(PW_LOG_DEBUG, "Parsing PKGBUILD architectures\n");

			PARSE_BASH_ARRAY_PREAMBLE(line);
			parse_bash_array(&(pkg->arch), fp, buf, line, 1);
		} else if (!strncmp(line, "build", 5)) {
			break;
		}
	}
}
Esempio n. 6
0
int powaur_crawl(alpm_list_t *targets)
{
    int ret = 0;
    char cwd[PATH_MAX];
    if (!getcwd(cwd, PATH_MAX)) {
        return error(PW_ERR_GETCWD);
    }

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

    struct pw_hashdb *hashdb = build_hashdb();
    if (!hashdb) {
        pw_fprintf(PW_LOG_ERROR, stderr, "Unable to build hash database!\n");
        ret = -1;
    }

    alpm_list_t *i, *target_pkgs;
    struct graph *graph;
    struct stack *topost = stack_new(sizeof(int));
    int have_cycles;
    for (i = targets; i; i = i->next) {
        stack_reset(topost);
        graph = NULL;
        target_pkgs = alpm_list_add(NULL, i->data);
        build_dep_graph(&graph, hashdb, target_pkgs, RESOLVE_THOROUGH);
        if (have_cycles) {
            printf("Cyclic dependencies for package \"%s\"\n", i->data);
        }

        graph_toposort(graph, topost);
        if (stack_empty(topost)) {
            printf("Package \"%s\" has no dependencies.\n", i->data);
        } else {
            printf("\n");
            pw_printf(PW_LOG_INFO, "\"%s\" topological order: ", i->data);
            print_topo_order(graph, topost);
        }

        graph_free(graph);
        alpm_list_free(target_pkgs);
    }

    stack_free(topost);
    hashdb_free(hashdb);

    if (chdir(cwd)) {
        return error(PW_ERR_RESTORECWD);
    }
    return ret;
}
Esempio n. 7
0
/* Prints immediate dependencies */
static void print_immediate_deps(struct pw_hashdb *hashdb)
{
	alpm_list_t *i;
	enum pkgfrom_t *from = NULL;

	if (!hashdb->immediate_deps) {
		pw_printf(PW_LOG_NORM, "\nNo dependencies found.\n\n");
		return;
	}

	printf("\n");
	pw_printf(PW_LOG_INFO, "Dependencies:\n");
	for (i = hashdb->immediate_deps; i; i = i->next) {
		from = hashmap_search(hashdb->pkg_from, i->data);
		switch (*from) {
		case PKG_FROM_LOCAL:
			pw_printf(PW_LOG_NORM, "%s%s (installed)%s\n", color.bgreen, i->data,
					  color.nocolor);
			break;
		case PKG_FROM_SYNC:
			pw_printf(PW_LOG_NORM, "%s%s (found in sync)%s\n", color.bblue, i->data,
					  color.nocolor);
			break;
		case PKG_FROM_AUR:
			/* Magic happens here */
			if (hash_search(hashdb->aur_outdated, (void *) i->data)) {
				pw_printf(PW_LOG_NORM, "%s%s (AUR target)%s\n",
						  color.bred, i->data, color.nocolor);
			} else {
				struct pkgpair pkgpair;
				pkgpair.pkgname = i->data;
				if (hash_search(hashdb->aur, &pkgpair)) {
					pw_printf(PW_LOG_NORM, "%s%s (installed AUR)%s\n", color.bblue,
							  i->data, color.nocolor);
				} else {
					/* New AUR package */
					pw_printf(PW_LOG_NORM, "%s%s (AUR dep)%s\n", color.bmag, i->data,
							  color.nocolor);
				}
			}
			break;
		default:
			/* Shouldn't happen */
			pw_printf(PW_LOG_NORM, "Unknown\n");
			break;
		}
	}
	printf("\n");
}
Esempio n. 8
0
/* Installs packages from the AUR
 * Assumes we are already in directory with all the relevant PKGBUILDS dled
 *
 * @param hashdb hash database
 * @param targets targets to be installed, in topo order
 */
static int topo_install(struct pw_hashdb *hashdb, alpm_list_t *targets)
{
	alpm_list_t *i;
	int ret;

	pw_printf(PW_LOG_INFO, "Targets (%d):\n", alpm_list_count(targets));
	print_list_color(targets, color.bmag);

	for (i = targets; i; i = i->next) {
		ret = install_single_package(i->data);
		if (ret == -2) {
			return ret;
		}
	}
	return 0;
}
Esempio n. 9
0
/* @param reload set to > 0 if reloading libalpm so that cachedirs can be
 * reinitialized.
 */
static int setup_pacman_environment(int reload)
{
	enum _alpm_errno_t err;
	alpm_list_t *i;
	if (reload) {
		pw_printf(PW_LOG_DEBUG, "Reloading pacman configuration\n");
		pacman_cachedirs = NULL;
	}

	if (parse_pmconfig()) {
		/* Free cachedirs */
		FREELIST(pacman_cachedirs);
		return error(PW_ERR_PM_CONF_PARSE);
	}

	if (!pacman_rootdir) {
		pacman_rootdir = xstrdup(PACMAN_DEF_ROOTDIR);
	}

	if (!pacman_dbpath) {
		pacman_dbpath = xstrdup(PACMAN_DEF_DBPATH);
	}

	if (!pacman_cachedirs) {
		pacman_cachedirs = alpm_list_add(pacman_cachedirs,
										 xstrdup(PACMAN_DEF_CACHEDIR));
	}

	alpm_option_set_cachedirs(config->handle, pacman_cachedirs);
	config->handle = alpm_initialize(pacman_rootdir, pacman_dbpath, &err);
	if (!config->handle) {
		return error(PW_ERR_INIT_ALPM_HANDLE);
	}
	/* Register sync dbs */
	for (i = pacman_syncdbs; i; i = i->next) {
		if (!alpm_db_register_sync(config->handle, (const char *) i->data,
								   ALPM_SIG_USE_DEFAULT)) {
			return error(PW_ERR_INIT_ALPM_REGISTER_SYNC);
		}
	}

	return 0;
}
Esempio n. 10
0
File: conf.c Progetto: rctay/powaur
/* fp is guaranteed to be non-NULL.
 * returns 0 on success, -1 on failure, 1 if not all options specified
 */
int parse_powaur_config(FILE *fp)
{
	int ret, parsed;
	char buf[PATH_MAX];
	char *line, *key, *val;
	size_t len;

	ret = parsed = 0;

	while (line = fgets(buf, PATH_MAX, fp)) {
		line = strtrim(line);
		len = strlen(line);

		/* Ignore empty lines and comments */
		if (!len || line[0] == '#') {
			continue;
		}

		val = strchr(line, '=');
		if (!val) {
			continue;
		}

		*val = 0;
		++val;

		key = strtrim(line);
		val = strtrim(val);

		if (!strcmp(key, "Editor")) {
			if (powaur_editor) {
				pw_fprintf(PW_LOG_ERROR, stderr, "%s%sRepeated Editor option!\n",
						   comstrs.tab, comstrs.tab);
				ret = -1;
				goto cleanup;
			}

			powaur_editor = strdup(val);
			if (!powaur_editor) {
				ret = -1;
				goto cleanup;
			}

			++parsed;
			pw_printf(PW_LOG_DEBUG, "%s%sParsed Editor = %s\n", comstrs.tab,
					  comstrs.tab, powaur_editor);

		} else if (!strcmp(key, "TmpDir")) {
			if (powaur_dir) {
				pw_fprintf(PW_LOG_ERROR, stderr, "%s%sRepeated TmpDir option!\n",
						   comstrs.tab, comstrs.tab);
				ret = -1;
				goto cleanup;
			}

			powaur_dir = strdup(val);
			if (!powaur_dir) {
				ret = -1;
				goto cleanup;
			}

			++parsed;
			pw_printf(PW_LOG_DEBUG, "%s%sParsed TmpDir = %s\n", comstrs.tab,
					  comstrs.tab, powaur_dir);
		}
	}

cleanup:

	if (ret) {
		if (!parsed) {
			free(powaur_editor);
			free(powaur_dir);
			powaur_editor = powaur_dir = NULL;
			return -1;
		} else {
			return 1;
		}
	}

	return 0;
}
Esempio n. 11
0
File: conf.c Progetto: rctay/powaur
/* Parse /etc/pacman.conf
 * We are hoping that the user does not remove the commented lines
 * under the [options] section.
 *
 * If there is insufficient information, we will fallback to the defaults.
 */
int parse_pmconfig(void)
{
	int ret = 0;
	int len;

	FILE *fp;
	char buf[PATH_MAX];
	char *line;

	int in_options = 0;
	int parsed_options = 0;

	fp = fopen(comstrs.pmconf, "r");
	ASSERT(fp != NULL, RET_ERR(PW_ERR_PM_CONF_OPEN, -1));

	pw_printf(PW_LOG_DEBUG, "%s : Parsing %s\n", __func__, comstrs.pmconf);

	while (line = fgets(buf, PATH_MAX, fp)) {
		line = strtrim(line);
		len = strlen(line);

		/* Ignore empty lines / Comments */
		if (len == 0 || (!in_options && line[0] == '#')) {
			continue;
		}

		/* Entering a section */
		if (line[0] == '[' && line[len-1] == ']') {

			line[len-1] = 0;
			++line;
			line = strtrim(line);

			/* Get new length of line */
			len = strlen(line);

			if (!strcmp(line, comstrs.opt)) {
				if (parsed_options) {
					pw_printf(PW_LOG_ERROR, "%sRepeated %s section in %s\n",
							  comstrs.tab, comstrs.opt, comstrs.pmconf);
					ret = -1;
					goto cleanup;
				}

				pw_printf(PW_LOG_DEBUG, "%sParsing [%s] section of %s\n",
						  comstrs.tab, comstrs.opt, comstrs.pmconf);

				parsed_options = 1;
				in_options = 1;
				continue;

			} else if (len == 0) {
				pw_printf(PW_LOG_DEBUG, "%sEmpty section in %s\n",
						  comstrs.tab, comstrs.pmconf);
				ret = -1;
				goto cleanup;
			} else {
				/* Must be a repository
				 * We just add the repository for now
				 */
				in_options = 0;

				pw_printf(PW_LOG_DEBUG, "%sParsing Repo [%s]\n",
						  comstrs.tab, line);

				if (!alpm_db_register_sync(line)) {
					pw_printf(PW_LOG_ERROR, "%sFailed to register %s db\n",
							  comstrs.tab, line);
					goto cleanup;
				}

				pw_printf(PW_LOG_DEBUG, "%sRegistering sync database '%s'\n",
						  comstrs.tab, line);
			}

		} else if (in_options) {
			if (ret = _parse_pmoption(line)) {
				break;
			}

			continue;
		}
	}

cleanup:
	fclose(fp);
	return ret;
}
Esempio n. 12
0
File: conf.c Progetto: rctay/powaur
/* Line is assumed to have been strtrim'ed
 */
static int _parse_pmoption(char *line)
{
	static int rootdir_com, rootdir;
	static int dbpath_com, dbpath;
	static int cachedir_com, cachedir;

	int len;

	if (line[0] == '#') {

		/* Look for default settings first. */
		++line;
		line = strtrim(line);
		len = strlen(line);

		if (len == 0) {
			return 0;
		}

		if (!strncmp(line, comstrs.rootdir, 7)) {
			parse_pmoption_keyval(&rootdir, &rootdir_com, line, comstrs.rootdir,
								  &pacman_rootdir, 1);

		} else if (!strncmp(line, comstrs.dbpath, 6)) {
			parse_pmoption_keyval(&dbpath, &dbpath_com, line, comstrs.dbpath,
								  &pacman_dbpath, 1);

		} else if (!strncmp(line, comstrs.cachedir, 8)) {
			parse_pmoption_repeat(&cachedir, &cachedir_com, line,
								  comstrs.cachedir, setrepeat_cachedir,
								  free_cachedir, (void **) &pacman_cachedirs, 1);

			pw_printf(PW_LOG_DEBUG, "%s%sCachedir default:\n", comstrs.tab,
					  comstrs.tab);

			indent_print(PW_LOG_DEBUG, pacman_cachedirs, 12);
		}

	} else {
		/* Non-commented, ie. official stuff */

		if (!strncmp(line, comstrs.rootdir, 7)) {
			if (rootdir) {
				pw_printf(PW_LOG_ERROR, "%s%sRepeated %s\n",
						  comstrs.tab, comstrs.tab, comstrs.rootdir);
				return -1;
			}

			parse_pmoption_keyval(&rootdir, &rootdir_com, line, comstrs.rootdir,
								  &pacman_rootdir, 0);

		} else if (!strncmp(line, comstrs.dbpath, 6)) {
			if (dbpath) {
				pw_printf(PW_LOG_ERROR, "%s%sRepeated %s\n",
						  comstrs.tab, comstrs.tab, comstrs.dbpath);
				return -1;
			}

			parse_pmoption_keyval(&dbpath, &dbpath_com, line, comstrs.dbpath,
								  &pacman_dbpath, 0);

		} else if (!strncmp(line, comstrs.cachedir, 8)) {
			if (cachedir) {
				pw_printf(PW_LOG_ERROR, "%s%sRepeated %s\n", comstrs.tab,
						  comstrs.tab, comstrs.cachedir);
				return -1;
			}

			parse_pmoption_repeat(&cachedir, &cachedir_com, line,
								  comstrs.cachedir, setrepeat_cachedir,
								  free_cachedir, (void **) &pacman_cachedirs, 0);

			pw_printf(PW_LOG_DEBUG, "%s%sCachedir final:\n", comstrs.tab,
					  comstrs.tab);
			indent_print(PW_LOG_DEBUG, pacman_cachedirs, 12);
		}
	}

	return 0;
}
Esempio n. 13
0
/* -Su, checks AUR packages */
static int sync_upgrade(CURL *curl, alpm_list_t *targets)
{
	int ret = 0;
	int cnt = 0;
	int upgrade_all;
	struct pkgpair pkgpair;
	struct pw_hashdb *hashdb = build_hashdb();
	if (!hashdb) {
		pw_fprintf(PW_LOG_ERROR, stderr, "Failed to build hash database.");
		return -1;
	}

	/* Make sure that packages are from AUR */
	alpm_list_t *i, *new_targs = NULL;
	for (i = targets; i; i = i->next) {
		pkgpair.pkgname = i->data;
		if (!hash_search(hashdb->aur, &pkgpair)) {
			if (cnt++) {
				printf(", ");
			}

			pw_printf(PW_LOG_NORM, "%s", i->data);
		} else {
			new_targs = alpm_list_add(new_targs, i->data);
		}
	}

	if (cnt > 1) {
		printf(" are not AUR packages and will not be checked.\n");
	} else if (cnt == 1) {
		printf(" is not an AUR package and will not be checked.\n");
	}

	alpm_list_t *outdated_pkgs = NULL;
	if (!targets) {
		/* Check all AUR packages */
		outdated_pkgs = get_outdated_pkgs(curl, hashdb, NULL);
	} else {
		if (!new_targs) {
			goto cleanup;
		}

		outdated_pkgs = get_outdated_pkgs(curl, hashdb, new_targs);
	}

	if (!outdated_pkgs) {
		pw_printf(PW_LOG_INFO, "All AUR packages are up to date.\n");
		goto cleanup;
	}

	printf("\n");
	pw_printf(PW_LOG_INFO, "Targets:\n");
	print_aurpkg_list(outdated_pkgs);
	printf("\n");

	/* --check, don't upgrade */
	if (config->op_s_check) {
		goto cleanup;
	}

	upgrade_all = config->noconfirm || yesno("Do you wish to upgrade the above packages?");
	if (upgrade_all) {
		/* Experimental */
		alpm_list_t *final_targets = NULL;
		struct aurpkg_t *aurpkg;
		for (i = outdated_pkgs; i; i = i->next) {
			aurpkg = i->data;
			final_targets = alpm_list_add(final_targets, aurpkg->name);
		}
		ret = upgrade_pkgs(final_targets, hashdb);
		alpm_list_free(final_targets);
	}

cleanup:
	alpm_list_free_inner(outdated_pkgs, (alpm_list_fn_free) aurpkg_free);
	alpm_list_free(outdated_pkgs);
	alpm_list_free(new_targs);
	hashdb_free(hashdb);
	return ret;
}
Esempio n. 14
0
/* Returns a list of outdated AUR packages among targets or all AUR packages.
 * The list and the packages are to be freed by the caller.
 *
 * @param curl curl easy handle
 * @param targets list of strings (package names) that are _definitely_ AUR packages
 */
static alpm_list_t *get_outdated_pkgs(CURL *curl, struct pw_hashdb *hashdb,
									  alpm_list_t *targets)
{
	alpm_list_t *i;
	alpm_list_t *outdated_pkgs = NULL;
	alpm_list_t *pkglist, *targs;
	struct pkgpair pkgpair;
	struct pkgpair *pkgpair_ptr;
	struct aurpkg_t *aurpkg;
	const char *pkgname, *pkgver;

	if (targets) {
		targs = targets;
	} else {
		targs = NULL;
		alpm_list_t *tmp_targs = hash_to_list(hashdb->aur);
		for (i = tmp_targs; i; i = i->next) {
			pkgpair_ptr = i->data;
			targs = alpm_list_add(targs, (void *) pkgpair_ptr->pkgname);
		}
		alpm_list_free(tmp_targs);
	}

	for (i = targs; i; i = i->next) {
		pkglist = query_aur(curl, i->data, AUR_QUERY_INFO);
		if (!pkglist) {
			continue;
		}

		pkgpair.pkgname = i->data;
		pkgpair_ptr = hash_search(hashdb->aur, &pkgpair);
		if (!pkgpair_ptr) {
			/* Shouldn't happen */
			pw_fprintf(PW_LOG_ERROR, stderr, "Unable to find AUR package \"%s\""
					   "in hashdb!\n", i->data);
		}

		aurpkg = pkglist->data;
		pkgver = alpm_pkg_get_version(pkgpair_ptr->pkg);
		pkgname = i->data;

		if (alpm_pkg_vercmp(aurpkg->version, pkgver) > 0) {
			/* Just show outdated package for now */
			pw_printf(PW_LOG_INFO, "%s %s is outdated, %s%s%s%s is available\n",
					  pkgname, pkgver, color.bred, aurpkg->version,
					  color.nocolor, color.bold);

			/* Add to upgrade list */
			outdated_pkgs = alpm_list_add(outdated_pkgs, aurpkg);
			pkglist->data = NULL;
		} else if (config->verbose) {
			pw_printf(PW_LOG_INFO, "%s %s is up to date.\n", pkgname,
					  pkgver);
		}

		alpm_list_free_inner(pkglist, (alpm_list_fn_free) aurpkg_free);
		alpm_list_free(pkglist);
	}

	if (!targets) {
		alpm_list_free(targs);
	}
	return outdated_pkgs;
}
Esempio n. 15
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;
}
Esempio n. 16
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;
}
Esempio n. 17
0
static int setup_powaur_config(void)
{
	/* Check the following places for logfile:
	 * $XDG_CONFIG_HOME
	 * $HOME
	 *
	 * Then fallback to default settings
	 */

	int ret = -1;
	FILE *fp = NULL;
	char *dir;
	char buf[PATH_MAX];
	struct stat st;

	pw_printf(PW_LOG_DEBUG, "%s: Setting up powaur configuration\n", __func__);

	dir = getenv("XDG_CONFIG_HOME");
	if (dir) {
		snprintf(buf, PATH_MAX, "%s/%s", dir, PW_CONF);

		if (!stat(buf, &st)) {
			fp = fopen(buf, "r");
			if (!fp) {
				goto check_home;
			}

			pw_printf(PW_LOG_DEBUG, "%sParsing %s\n", TAB, buf);
			parse_powaur_config(fp);
			fclose(fp);
			goto cleanup;
		}
	}

check_home:
	/* Check $HOME */
	dir = getenv("HOME");
	if (dir) {
		snprintf(buf, PATH_MAX, "%s/.config/%s", dir, PW_CONF);

		if (!stat(buf, &st)) {
			fp = fopen(buf, "r");
			if (!fp) {
				goto cleanup;
			}

			pw_printf(PW_LOG_DEBUG, "%sParsing %s\n", TAB, buf);
			parse_powaur_config(fp);
			fclose(fp);
		}
	}

cleanup:

	/* Use default settings for unspecified options */
	if (!powaur_dir) {
		uid_t myuid = geteuid();
		struct passwd *passwd_struct = getpwuid(myuid);
		if (!passwd_struct) {
			powaur_dir = xstrdup(PW_DEF_DIR);
		} else {
			snprintf(buf, PATH_MAX, "%s-%s", PW_DEF_DIR, passwd_struct->pw_name);
			powaur_dir = xstrdup(buf);
		}

		pw_printf(PW_LOG_DEBUG, "%sFalling back to default directory %s\n",
				  TAB, powaur_dir);
	}

	if (!powaur_editor) {
		powaur_editor = xstrdup(PW_DEF_EDITOR);
		pw_printf(PW_LOG_DEBUG, "%sFalling back to default editor %s\n",
				  TAB, powaur_editor);
	}

	if (powaur_maxthreads <= 0 || powaur_maxthreads > PW_DEF_MAXTHREADS) {
		powaur_maxthreads = PW_DEF_MAXTHREADS;
	}

	config->maxthreads = powaur_maxthreads;
	pw_printf(PW_LOG_DEBUG, "%sMaximum no. of threads = %d\n", TAB,
			  config->maxthreads);

	return 0;
}
Esempio n. 18
0
/* TODO: Return version string for >=, >, <, =.
 * TODO: provides, etc, ":" for optdepends
 * Refer to https://wiki.archlinux.org/index.php/Pkgbuild for details.
 */
static void parse_bash_array(alpm_list_t **list, FILE *fp,
							 char *buf, char *line, int preserve_ver)
{
	static const char *delim = " ";

	int len;
	int can_break = 0;
	char *token, *saveptr;
	char *tmpstr;

	/* Parse multi-line bash array */
	for (; !feof(fp) && !can_break; line = fgets(buf, PATH_MAX, fp)) {

		line = strtrim(line);
		len = strlen(line);

		if (len == 0) {
			continue;
		} else if (line[len - 1] == ')') {
			can_break = 1;
		}

		for (token = strtok_r(line, delim, &saveptr), line = NULL;
			 token; token = strtok_r(line, delim, &saveptr)) {

			token = strtrim(token);

			/* Remove quotes */
			if (token[0] == '\'' || token[0] == '"') {
				++token;
			}

			len = strlen(token);
			if (token[len-1] == '\'' || token[len-1] == '"') {
				token[len-1] = 0;
				--len;
			}

			if (len == 0) {
				continue;
			} else if (token[0] == ')') {
				can_break = 1;
				break;
			} else if (token[len-1] == ')') {
				can_break = 1;
				token[len-1] = 0;
				token = strtrim(token);

				if (token[len-2] == '\'' || token[len-2] == '"') {
					token[len-2] = 0;
				}
			}

			if (preserve_ver) {
				*list = alpm_list_add(*list, strdup(token));
			} else {
				token = strtrim_ver(token);
				*list = alpm_list_add(*list, strdup(token));
			}

			pw_printf(PW_LOG_DEBUG, "%sParsed \"%s\"\n", TAB, token);
		}
	}
}