#include <sys/stat.h>
#include <sys/param.h>
#include <err.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pkg.h>
#include "pkgcli.h"
static bool
_find_repo(c_charv_t *reponames, const char *name)
{
vec_foreach(*reponames, i) {
if (STREQ(name, reponames->d[i]))
return (true);
}
return(false);
}
int
pkgcli_update(bool force, bool strict, c_charv_t *reponames)
{
int retcode = EPKG_FATAL, update_count = 0, total_count = 0;
struct pkg_repo *r = NULL;
if (pkgdb_access2(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
PKGDB_DB_REPO, reponames) == EPKG_ENOACCESS)
return (EPKG_OK);
if (pkg_repos_total_count() == 0) {
fprintf(stderr, "No active remote repositories configured.\n");
return (EPKG_FATAL);
}
while (pkg_repos(&r) == EPKG_OK) {
if (reponames->len > 0 ) {
if (!_find_repo(reponames, pkg_repo_name(r)))
continue;
} else {
if (!pkg_repo_enabled(r))
continue;
}
if (!quiet)
printf("Updating %s repository catalogue...\n",
pkg_repo_name(r));
retcode = pkg_update(r, force);
if (retcode == EPKG_UPTODATE) {
retcode = EPKG_OK;
if (!quiet) {
printf("%s repository is up to date.\n",
pkg_repo_name(r));
}
}
else if (retcode != EPKG_OK && strict)
retcode = EPKG_FATAL;
if (retcode == EPKG_OK) {
update_count++;
}
total_count ++;
}
if (total_count == 0) {
retcode = EPKG_FATAL;
if (!quiet) {
printf("No repositories are enabled.\n");
}
}
else if (update_count == total_count) {
if (!quiet) {
if (reponames == NULL || reponames->len == 0)
printf("All repositories are up to date.\n");
else {
vec_foreach(*reponames, i)
printf("%s%s", i == 0 ? "" : ", ", reponames->d[i]);
printf(" %s up to date.\n", reponames->len == 1 ? "is" : "are");
}
}
}
else if (total_count == 1) {
if (!quiet) {
printf("Error updating repositories!\n");
}
}
else {
if (!quiet) {
printf("Error updating repositories!\n");
}
if (strict) {
retcode = EPKG_FATAL;
}
}
return (retcode);
}
void
usage_update(void)
{
fprintf(stderr, "Usage: pkg update [-fq] [-r reponame]\n\n");
fprintf(stderr, "For more information, see 'pkg help update'.\n");
}
int
exec_update(int argc, char **argv)
{
int ret;
int ch;
c_charv_t reponames = vec_init();
struct option longopts[] = {
{ "force", no_argument, NULL, 'f' },
{ "quiet", no_argument, NULL, 'q' },
{ "repository", required_argument, NULL, 'r' },
{ NULL, 0, NULL, 0 },
};
while ((ch = getopt_long(argc, argv, "+fqr:", longopts, NULL)) != -1) {
switch (ch) {
case 'f':
force = true;
break;
case 'q':
quiet = true;
break;
case 'r':
vec_push(&reponames, optarg);
break;
default:
usage_update();
return (EXIT_FAILURE);
}
}
argc -= optind;
if (argc != 0) {
usage_update();
return (EXIT_FAILURE);
}
ret = pkgdb_access2(PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
PKGDB_DB_REPO, &reponames);
if (ret == EPKG_ENOACCESS) {
warnx("Insufficient privileges to update the repository "
"catalogue.");
return (EXIT_FAILURE);
} else if (ret != EPKG_OK)
return (EXIT_FAILURE);
ret = pkgcli_update(force, true, &reponames);
return ((ret == EPKG_OK) ? EXIT_SUCCESS : EXIT_FAILURE);
}