Esempio n. 1
0
END_TEST

START_TEST(test_two_sacks)
{
    /* This clumsily mimics create_ut_sack() and setup_with() to
     * create a second HySack. */
    char *tmpdir = solv_dupjoin(test_globals.tmpdir, "/tmp", NULL);
    HySack sack1 = hy_sack_create(tmpdir, TEST_FIXED_ARCH, NULL, NULL,
                                  HY_MAKE_CACHE_DIR);
    Pool *pool1 = sack_pool(sack1);
    const char *path = pool_tmpjoin(pool1, test_globals.repo_dir,
                                    "change.repo", NULL);
    fail_if(load_repo(pool1, "change", path, 0));
    HyPackage pkg1 = by_name(sack1, "penny-lib");
    fail_if(pkg1 == NULL);

    HySack sack2 = test_globals.sack;
    Pool *pool2 = sack_pool(sack2);
    HyPackage pkg2 = by_name(sack2, "penny-lib");
    fail_if(pkg2 == NULL);

    /* "penny-lib" is in both pools but at different offsets */
    Solvable *s1 = pool_id2solvable(pool1, pkg1->id);
    Solvable *s2 = pool_id2solvable(pool2, pkg2->id);
    fail_if(s1->name == s2->name);

    fail_if(hy_package_cmp(pkg1, pkg2) != 0);

    hy_package_free(pkg1);
    hy_package_free(pkg2);

    hy_sack_free(sack1);
    solv_free(tmpdir);
}
Esempio n. 2
0
END_TEST

START_TEST(test_checksum_write_read)
{
    char *new_file = solv_dupjoin(test_globals.tmpdir,
                                  "/test_checksum_write_read", NULL);
    build_test_file(new_file);

    unsigned char cs_computed[CHKSUM_BYTES];
    unsigned char cs_read[CHKSUM_BYTES];
    FILE *fp = fopen(new_file, "r");
    checksum_fp(cs_computed, fp);
    // fails, file opened read-only:
    fail_unless(checksum_write(cs_computed, fp) == 1);
    fclose(fp);
    fp = fopen(new_file, "r+");
    fail_if(checksum_write(cs_computed, fp));
    fclose(fp);
    fp = fopen(new_file, "r");
    fail_if(checksum_read(cs_read, fp));
    fail_if(checksum_cmp(cs_computed, cs_read));
    fclose(fp);

    g_free(new_file);
}
Esempio n. 3
0
static int
init_test_globals(struct TestGlobals_s *tg, const char *repo_dir)
{
    int const len = strlen(repo_dir);
    if (repo_dir[len -1] != '/')
	tg->repo_dir = solv_dupjoin(repo_dir, "/", NULL);
    else
	tg->repo_dir = solv_strdup(repo_dir);
    tg->tmpdir = solv_strdup(UNITTEST_DIR);
    if (mkdtemp(tg->tmpdir) == NULL)
	return 1;
    tg->sack = NULL;
    return 0;
}
Esempio n. 4
0
END_TEST

START_TEST(test_add_cmdline_package)
{
    HifSack *sack = hif_sack_new();
    hif_sack_set_cachedir(sack, test_globals.tmpdir);

    char *path_mystery = solv_dupjoin(TESTDATADIR, "/hawkey/yum/mystery-devel-19.67-1.noarch.rpm", NULL);
    HifPackage *pkg_mystery = hif_sack_add_cmdline_package(sack, path_mystery);
    char *location_mystery = hif_package_get_location(pkg_mystery);
    ck_assert_str_eq(path_mystery, location_mystery);

    char *path_tour = solv_dupjoin(TESTDATADIR, "/hawkey/yum/tour-4-6.noarch.rpm", NULL);
    HifPackage *pkg_tour = hif_sack_add_cmdline_package(sack, path_tour);
    char *location_tour = hif_package_get_location(pkg_tour);
    ck_assert_str_eq(path_tour, location_tour);

    g_free(path_mystery);
    g_free(location_mystery);
    g_free(path_tour);
    g_free(location_tour);
    g_object_unref(sack);
}
Esempio n. 5
0
END_TEST

START_TEST(test_checksum)
{
    /* create a new file, edit it a bit */
    char *new_file = solv_dupjoin(test_globals.tmpdir,
                                  "/test_checksum", NULL);
    build_test_file(new_file);

    unsigned char cs1[CHKSUM_BYTES];
    unsigned char cs2[CHKSUM_BYTES];
    unsigned char cs1_sum[CHKSUM_BYTES];
    unsigned char cs2_sum[CHKSUM_BYTES];
    bzero(cs1, CHKSUM_BYTES);
    bzero(cs2, CHKSUM_BYTES);
    bzero(cs1_sum, CHKSUM_BYTES);
    bzero(cs2_sum, CHKSUM_BYTES);
    fail_if(checksum_cmp(cs1, cs2)); // tests checksum_cmp

    /* take the first checksums */
    FILE *fp;
    fail_if((fp = fopen(new_file, "r")) == NULL);
    fail_if(checksum_fp(cs1, fp));
    fail_if(checksum_stat(cs1_sum, fp));
    fclose(fp);
    /* the taken checksum are not zeros anymore */
    fail_if(checksum_cmp(cs1, cs2) == 0);
    fail_if(checksum_cmp(cs1_sum, cs2_sum) == 0);

    /* append something */
    fail_if((fp = fopen(new_file, "a")) == NULL);
    fail_unless(fwrite("X", 1, 1, fp) == 1);
    fclose(fp);

    /* take the second checksums */
    fail_if((fp = fopen(new_file, "r")) == NULL);
    fail_if(checksum_stat(cs2, fp));
    fail_if(checksum_stat(cs2_sum, fp));
    fclose(fp);
    fail_unless(checksum_cmp(cs1, cs2));
    fail_unless(checksum_cmp(cs1_sum, cs2_sum));

    g_free(new_file);
}
Esempio n. 6
0
char *
abspath(const char *path)
{
    const int len = strlen(path);
    if (len <= 1) {
	hy_errno = HY_E_OP;
	return NULL;
    }

    if (path[0] == '/')
	return solv_strdup(path);

    char cwd[PATH_MAX];
    if (!getcwd(cwd, PATH_MAX)) {
	hy_errno = HY_E_FAILED;
	return NULL;
    }

    return solv_dupjoin(cwd, "/", path);
}
Esempio n. 7
0
int
main(int argc, char **argv)
{
  Pool *pool;
  Queue job;
  Queue solq;
  Solver *solv;
  char *result = 0;
  int resultflags = 0;
  int debuglevel = 0;
  int writeresult = 0;
  int multijob = 0;
  int rescallback = 0;
  int c;
  int ex = 0;
  const char *list = 0;
  FILE *fp;
  const char *p;

  queue_init(&solq);
  while ((c = getopt(argc, argv, "vmrhl:s:")) >= 0)
    {
      switch (c)
      {
        case 'v':
          debuglevel++;
          break;
        case 'r':
          writeresult++;
          break;
        case 'm':
          rescallback = 1;
          break;
        case 'h':
	  usage(0);
          break;
        case 'l':
	  list = optarg;
          break;
        case 's':
	  if ((p = strchr(optarg, ':')))
	    queue_push2(&solq, atoi(optarg), atoi(p + 1));
	  else
	    queue_push2(&solq, 1, atoi(optarg));
          break;
        default:
	  usage(1);
          break;
      }
    }
  if (optind == argc)
    usage(1);
  for (; optind < argc; optind++)
    {
      pool = pool_create();
      pool_setdebuglevel(pool, debuglevel);

      fp = fopen(argv[optind], "r");
      if (!fp)
	{
	  perror(argv[optind]);
	  exit(0);
	}
      while (!feof(fp))
	{
	  queue_init(&job);
	  result = 0;
	  resultflags = 0;
	  solv = testcase_read(pool, fp, argv[optind], &job, &result, &resultflags);
	  if (!solv)
	    {
	      pool_free(pool);
	      exit(1);
	    }

	  if (!multijob && !feof(fp))
	    multijob = 1;

	  if (multijob)
	    printf("test %d:\n", multijob++);
	  if (list)
	    {
	      queue_empty(&job);
	      selection_make(pool, &job, list, SELECTION_NAME|SELECTION_PROVIDES|SELECTION_FILELIST|SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL|SELECTION_GLOB|SELECTION_FLAT);
	      if (!job.elements)
		printf("No match\n");
	      else
		{
		  Queue q;
		  int i;
		  queue_init(&q);
		  selection_solvables(pool, &job, &q);
		  for (i = 0; i < q.count; i++)
		    printf("  - %s\n", testcase_solvid2str(pool, q.elements[i]));
		  queue_free(&q);
		}
	    }
	  else if (result || writeresult)
	    {
	      char *myresult, *resultdiff;
	      struct reportsolutiondata reportsolutiondata;
	      memset(&reportsolutiondata, 0, sizeof(reportsolutiondata));
	      if (rescallback)
		{
		  solv->solution_callback = reportsolutioncb;
		  solv->solution_callback_data = &reportsolutiondata;
		}
	      solver_solve(solv, &job);
	      solv->solution_callback = 0;
	      solv->solution_callback_data = 0;
	      if (!resultflags)
		resultflags = TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS;
	      myresult = testcase_solverresult(solv, resultflags);
	      if (rescallback && reportsolutiondata.result)
		{
		  reportsolutiondata.result = solv_dupjoin(reportsolutiondata.result, myresult, 0);
		  solv_free(myresult);
		  myresult = reportsolutiondata.result;
		}
	      if (writeresult)
		{
		  if (*myresult)
		    {
		      if (writeresult > 1)
			{
			  const char *p;
			  int i;
			  
			  printf("result ");
			  p = "%s";
			  for (i = 0; resultflags2str[i].str; i++)
			    if ((resultflags & resultflags2str[i].flag) != 0)
			      {
			        printf(p, resultflags2str[i].str);
			        p = ",%s";
			      }
			  printf(" <inline>\n");
			  p = myresult;
			  while (*p)
			    {
			      const char *p2 = strchr(p, '\n');
			      p2 = p2 ? p2 + 1 : p + strlen(p);
			      printf("#>%.*s", (int)(p2 - p), p);
			      p = p2;
			    }
			}
		      else
			printf("%s", myresult);
		    }
		}
	      else
		{
		  resultdiff = testcase_resultdiff(result, myresult);
		  if (resultdiff)
		    {
		      printf("Results differ:\n%s", resultdiff);
		      ex = 1;
		      solv_free(resultdiff);
		    }
		}
	      solv_free(result);
	      solv_free(myresult);
	    }
	  else
	    {
	      int pcnt = solver_solve(solv, &job);
	      if (pcnt && solq.count)
		{
		  int i, taken = 0;
		  for (i = 0; i < solq.count; i += 2)
		    {
		      if (solq.elements[i] > 0 && solq.elements[i] <= pcnt)
			if (solq.elements[i + 1] > 0 && solq.elements[i + 1] <=  solver_solution_count(solv, solq.elements[i]))
			  {
			    printf("problem %d: taking solution %d\n", solq.elements[i], solq.elements[i + 1]);
			    solver_take_solution(solv, solq.elements[i], solq.elements[i + 1], &job);
			    taken = 1;
			  }
		    }
		  if (taken)
		    pcnt = solver_solve(solv, &job);
		}
	      if (pcnt)
		{
		  int problem, solution, scnt;
		  printf("Found %d problems:\n", pcnt);
		  for (problem = 1; problem <= pcnt; problem++)
		    {
		      printf("Problem %d:\n", problem);
#if 1
		      solver_printprobleminfo(solv, problem);
#else
		      {
			Queue pq;
			int j;
			queue_init(&pq);
			solver_findallproblemrules(solv, problem, &pq);
			for (j = 0; j < pq.count; j++)
			  solver_printproblemruleinfo(solv, pq.elements[j]);
			queue_free(&pq);
		      }
#endif
		      printf("\n");
		      scnt = solver_solution_count(solv, problem);
		      for (solution = 1; solution <= scnt; solution++)
			{
			  printf("Solution %d:\n", solution);
			  solver_printsolution(solv, problem, solution);
			  printf("\n");
			}
		    }
		}
	      else
		{
		  Transaction *trans = solver_create_transaction(solv);
		  printf("Transaction summary:\n\n");
		  transaction_print(trans);
		  transaction_free(trans);
		}
	    }
	  queue_free(&job);
	  solver_free(solv);
	}
      pool_free(pool);
      fclose(fp);
    }
  queue_free(&solq);
  exit(ex);
}
Esempio n. 8
0
int
main(int argc, char **argv)
{
  Pool *pool;
  Repo *commandlinerepo = 0;
  Id *commandlinepkgs = 0;
  Id p;
  struct repoinfo *repoinfos, installedrepoinfo;
  int nrepoinfos = 0;
  int mainmode = 0, mode = 0;
  int i, newpkgs;
  Queue job, checkq;
  Solver *solv = 0;
  Transaction *trans;
  FILE **newpkgsfps;
  Queue repofilter;
  Queue kindfilter;
  Queue archfilter;
  int archfilter_src = 0;
  int cleandeps = 0;
  int forcebest = 0;
  char *rootdir = 0;
  char *keyname = 0;
  int keyname_depstr = 0;
  int debuglevel = 0;
  int answer, acnt = 0;

  argc--;
  argv++;
  while (argc && !strcmp(argv[0], "-d"))
    {
      debuglevel++;
      argc--;
      argv++;
    }
  if (!argv[0])
    usage(1);
  if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in"))
    {
      mainmode = MODE_INSTALL;
      mode = SOLVER_INSTALL;
    }
#if defined(SUSE) || defined(FEDORA)
  else if (!strcmp(argv[0], "patch"))
    {
      mainmode = MODE_PATCH;
      mode = SOLVER_INSTALL;
    }
#endif
  else if (!strcmp(argv[0], "erase") || !strcmp(argv[0], "rm"))
    {
      mainmode = MODE_ERASE;
      mode = SOLVER_ERASE;
    }
  else if (!strcmp(argv[0], "list") || !strcmp(argv[0], "ls"))
    {
      mainmode = MODE_LIST;
      mode = 0;
    }
  else if (!strcmp(argv[0], "info"))
    {
      mainmode = MODE_INFO;
      mode = 0;
    }
  else if (!strcmp(argv[0], "search") || !strcmp(argv[0], "se"))
    {
      mainmode = MODE_SEARCH;
      mode = 0;
    }
  else if (!strcmp(argv[0], "verify"))
    {
      mainmode = MODE_VERIFY;
      mode = SOLVER_VERIFY;
    }
  else if (!strcmp(argv[0], "update") || !strcmp(argv[0], "up"))
    {
      mainmode = MODE_UPDATE;
      mode = SOLVER_UPDATE;
    }
  else if (!strcmp(argv[0], "dist-upgrade") || !strcmp(argv[0], "dup"))
    {
      mainmode = MODE_DISTUPGRADE;
      mode = SOLVER_DISTUPGRADE;
    }
  else if (!strcmp(argv[0], "repos") || !strcmp(argv[0], "repolist") || !strcmp(argv[0], "lr"))
    {
      mainmode = MODE_REPOLIST;
      mode = 0;
    }
  else
    usage(1);

  for (;;)
    {
      if (argc > 2 && !strcmp(argv[1], "--root"))
	{
	  rootdir = argv[2];
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 1 && !strcmp(argv[1], "--clean"))
	{
	  cleandeps = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 1 && !strcmp(argv[1], "--best"))
	{
	  forcebest = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 1 && !strcmp(argv[1], "--depstr"))
	{
	  keyname_depstr = 1;
	  argc--;
	  argv++;
	}
      else if (argc > 2 && !strcmp(argv[1], "--keyname"))
	{
	  keyname = argv[2];
	  argc -= 2;
	  argv += 2;
	}
      else
	break;
    }

  set_userhome();
  pool = pool_create();
  pool_set_rootdir(pool, rootdir);

#if 0
  {
    const char *langs[] = {"de_DE", "de", "en"};
    pool_set_languages(pool, langs, sizeof(langs)/sizeof(*langs));
  }
#endif

  pool_setloadcallback(pool, load_stub, 0);
#ifdef SUSE
  pool->nscallback = nscallback;
#endif
  if (debuglevel)
    pool_setdebuglevel(pool, debuglevel);
  setarch(pool);
  pool_set_flag(pool, POOL_FLAG_ADDFILEPROVIDESFILTERED, 1);
  repoinfos = read_repoinfos(pool, &nrepoinfos);
  sort_repoinfos(repoinfos, nrepoinfos);

  if (mainmode == MODE_REPOLIST)
    {
      int j = 1;
      for (i = 0; i < nrepoinfos; i++)
	{
	  struct repoinfo *cinfo = repoinfos + i;
	  if (!cinfo->enabled)
	    continue;
	  printf("%d: %-20s %s (prio %d)\n", j++, cinfo->alias, cinfo->name, cinfo->priority);
	}
      exit(0);
    }
  memset(&installedrepoinfo, 0, sizeof(installedrepoinfo));
  if (!read_installed_repo(&installedrepoinfo, pool))
    exit(1);
  read_repos(pool, repoinfos, nrepoinfos);

  /* setup filters */
  queue_init(&repofilter);
  queue_init(&kindfilter);
  queue_init(&archfilter);
  while (argc > 1)
    {
      if (!strcmp(argv[1], "-i"))
	{
	  queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO, pool->installed->repoid);
	  argc--;
	  argv++;
	}
      else if (argc > 2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "--repo")))
	{
	  Id repoid = find_repo(argv[2], pool, repoinfos, nrepoinfos);
	  if (!repoid)
	    {
	      fprintf(stderr, "%s: no such repo\n", argv[2]);
	      exit(1);
	    }
	  /* SETVENDOR is actually wrong but useful */
	  queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO | SOLVER_SETVENDOR, repoid);
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 2 && !strcmp(argv[1], "--arch"))
	{
	  if (!strcmp(argv[2], "src") || !strcmp(argv[2], "nosrc"))
	    archfilter_src = 1;
	  queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, argv[2], 1), REL_ARCH, 1));
	  argc -= 2;
	  argv += 2;
	}
      else if (argc > 2 && (!strcmp(argv[1], "-t") || !strcmp(argv[1], "--type")))
	{
	  const char *kind = argv[2];
	  if (!strcmp(kind, "srcpackage"))
	    {
	      /* hey! should use --arch! */
	      queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, ARCH_SRC, REL_ARCH, 1));
	      archfilter_src = 1;
	      argc -= 2;
	      argv += 2;
	      continue;
	    }
	  if (!strcmp(kind, "package"))
	    kind = "";
	  if (!strcmp(kind, "all"))
	    queue_push2(&kindfilter, SOLVER_SOLVABLE_ALL, 0);
	  else
	    queue_push2(&kindfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, kind, 1), REL_KIND, 1));
	  argc -= 2;
	  argv += 2;
	}
      else
	break;
    }

  if (mainmode == MODE_SEARCH)
    {
      Queue sel, q;
      Dataiterator di;
      if (argc != 2)
	usage(1);
      pool_createwhatprovides(pool);
      queue_init(&sel);
      dataiterator_init(&di, pool, 0, 0, 0, argv[1], SEARCH_SUBSTRING|SEARCH_NOCASE);
      dataiterator_set_keyname(&di, SOLVABLE_NAME);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_set_keyname(&di, SOLVABLE_SUMMARY);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_set_keyname(&di, SOLVABLE_DESCRIPTION);
      dataiterator_set_search(&di, 0, 0);
      while (dataiterator_step(&di))
	queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
      dataiterator_free(&di);
      if (repofilter.count)
	selection_filter(pool, &sel, &repofilter);
	
      queue_init(&q);
      selection_solvables(pool, &sel, &q);
      queue_free(&sel);
      for (i = 0; i < q.count; i++)
	{
	  Solvable *s = pool_id2solvable(pool, q.elements[i]);
	  printf("  - %s [%s]: %s\n", pool_solvable2str(pool, s), s->repo->name, solvable_lookup_str(s, SOLVABLE_SUMMARY));
	}
      queue_free(&q);
      exit(0);
    }

  /* process command line packages */
  if (mainmode == MODE_LIST || mainmode == MODE_INFO || mainmode == MODE_INSTALL)
    {
      for (i = 1; i < argc; i++)
	{
	  if (!is_cmdline_package((const char *)argv[i]))
	    continue;
	  if (access(argv[i], R_OK))
	    {
	      perror(argv[i]);
	      exit(1);
	    }
	  if (!commandlinepkgs)
	    commandlinepkgs = solv_calloc(argc, sizeof(Id));
	  if (!commandlinerepo)
	    commandlinerepo = repo_create(pool, "@commandline");
	  p = add_cmdline_package(commandlinerepo, (const char *)argv[i]);
	  if (!p)
	    {
	      fprintf(stderr, "could not add '%s'\n", argv[i]);
	      exit(1);
	    }
	  commandlinepkgs[i] = p;
	}
      if (commandlinerepo)
	repo_internalize(commandlinerepo);
    }

#if defined(ENABLE_RPMDB)
  if (pool->disttype == DISTTYPE_RPM)
    addfileprovides(pool);
#endif
#ifdef SUSE
  add_autopackages(pool);
#endif
  pool_createwhatprovides(pool);

  if (keyname)
    keyname = solv_dupjoin("solvable:", keyname, 0);
  queue_init(&job);
  for (i = 1; i < argc; i++)
    {
      Queue job2;
      int flags, rflags;

      if (commandlinepkgs && commandlinepkgs[i])
	{
	  queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]);
	  continue;
	}
      queue_init(&job2);
      flags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_GLOB;
      flags |= SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL;
      if (kindfilter.count)
	flags |= SELECTION_SKIP_KIND;
      if (mode == MODE_LIST || archfilter_src)
	flags |= SELECTION_WITH_SOURCE;
      if (argv[i][0] == '/')
	flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0);
      if (!keyname)
        rflags = selection_make(pool, &job2, argv[i], flags);
      else
	{
	  if (keyname_depstr)
	    flags |= SELECTION_MATCH_DEPSTR;
          rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
	}
      if (repofilter.count)
	selection_filter(pool, &job2, &repofilter);
      if (archfilter.count)
	selection_filter(pool, &job2, &archfilter);
      if (kindfilter.count)
	selection_filter(pool, &job2, &kindfilter);
      if (!job2.count)
	{
	  flags |= SELECTION_NOCASE;
	  if (!keyname)
            rflags = selection_make(pool, &job2, argv[i], flags);
	  else
	    rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
	  if (repofilter.count)
	    selection_filter(pool, &job2, &repofilter);
	  if (archfilter.count)
	    selection_filter(pool, &job2, &archfilter);
	  if (kindfilter.count)
	    selection_filter(pool, &job2, &kindfilter);
	  if (job2.count)
	    printf("[ignoring case for '%s']\n", argv[i]);
	}
      if (!job2.count)
	{
	  fprintf(stderr, "nothing matches '%s'\n", argv[i]);
	  exit(1);
	}
      if (rflags & SELECTION_FILELIST)
        printf("[using file list match for '%s']\n", argv[i]);
      if (rflags & SELECTION_PROVIDES)
	printf("[using capability match for '%s']\n", argv[i]);
      queue_insertn(&job, job.count, job2.count, job2.elements);
      queue_free(&job2);
    }
  keyname = solv_free(keyname);

  if (!job.count && (mainmode == MODE_UPDATE || mainmode == MODE_DISTUPGRADE || mainmode == MODE_VERIFY || repofilter.count || archfilter.count || kindfilter.count))
    {
      queue_push2(&job, SOLVER_SOLVABLE_ALL, 0);
      if (repofilter.count)
	selection_filter(pool, &job, &repofilter);
      if (archfilter.count)
	selection_filter(pool, &job, &archfilter);
      if (kindfilter.count)
	selection_filter(pool, &job, &kindfilter);
    }
  queue_free(&repofilter);
  queue_free(&archfilter);
  queue_free(&kindfilter);

  if (!job.count && mainmode != MODE_PATCH)
    {
      printf("no package matched\n");
      exit(1);
    }

  if (mainmode == MODE_LIST || mainmode == MODE_INFO)
    {
      /* list mode, no solver needed */
      Queue q;
      queue_init(&q);
      for (i = 0; i < job.count; i += 2)
	{
	  int j;
	  queue_empty(&q);
	  pool_job2solvables(pool, &q, job.elements[i], job.elements[i + 1]);
	  for (j = 0; j < q.count; j++)
	    {
	      Solvable *s = pool_id2solvable(pool, q.elements[j]);
	      if (mainmode == MODE_INFO)
		{
		  const char *str;
		  printf("Name:        %s\n", pool_solvable2str(pool, s));
		  printf("Repo:        %s\n", s->repo->name);
		  printf("Summary:     %s\n", solvable_lookup_str(s, SOLVABLE_SUMMARY));
		  str = solvable_lookup_str(s, SOLVABLE_URL);
		  if (str)
		    printf("Url:         %s\n", str);
		  str = solvable_lookup_str(s, SOLVABLE_LICENSE);
		  if (str)
		    printf("License:     %s\n", str);
		  printf("Description:\n%s\n", solvable_lookup_str(s, SOLVABLE_DESCRIPTION));
		  printf("\n");
		}
	      else
		{
#if 1
		  const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de", 1);
#else
		  const char *sum = solvable_lookup_str_poollang(s, SOLVABLE_SUMMARY);
#endif
		  printf("  - %s [%s]\n", pool_solvable2str(pool, s), s->repo->name);
		  if (sum)
		    printf("    %s\n", sum);
		}
	    }
	}
      queue_free(&q);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(0);
    }

#if defined(SUSE) || defined(FEDORA)
  if (mainmode == MODE_PATCH)
    add_patchjobs(pool, &job);
#endif

  // add mode
  for (i = 0; i < job.count; i += 2)
    {
      job.elements[i] |= mode;
      if (mode == SOLVER_UPDATE && pool_isemptyupdatejob(pool, job.elements[i], job.elements[i + 1]))
	job.elements[i] ^= SOLVER_UPDATE ^ SOLVER_INSTALL;
      if (cleandeps)
        job.elements[i] |= SOLVER_CLEANDEPS;
      if (forcebest)
        job.elements[i] |= SOLVER_FORCEBEST;
    }

  // multiversion test
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae", 1));
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-base", 1));
  // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-extra", 1));
#if 0
  queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
  queue_push2(&job, SOLVER_ERASE|SOLVER_CLEANDEPS|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
#endif

rerunsolver:
  solv = solver_create(pool);
  solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
#ifdef FEDORA
  solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
#endif
  if (mainmode == MODE_ERASE)
    solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1);	/* don't nag */
  solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1);

  for (;;)
    {
      Id problem, solution;
      int pcnt, scnt;

      if (!solver_solve(solv, &job))
	break;
      pcnt = solver_problem_count(solv);
      printf("Found %d problems:\n", pcnt);
      for (problem = 1; problem <= pcnt; problem++)
	{
	  int take = 0;
	  printf("Problem %d/%d:\n", problem, pcnt);
	  solver_printprobleminfo(solv, problem);
	  printf("\n");
	  scnt = solver_solution_count(solv, problem);
	  for (solution = 1; solution <= scnt; solution++)
	    {
	      printf("Solution %d:\n", solution);
	      solver_printsolution(solv, problem, solution);
	      printf("\n");
	    }
	  for (;;)
	    {
	      char inbuf[128], *ip;
	      printf("Please choose a solution: ");
	      fflush(stdout);
	      *inbuf = 0;
	      if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
		{
		  printf("Abort.\n");
		  exit(1);
		}
	      while (*ip == ' ' || *ip == '\t')
		ip++;
	      if (*ip >= '0' && *ip <= '9')
		{
		  take = atoi(ip);
		  if (take >= 1 && take <= scnt)
		    break;
		}
	      if (*ip == 's')
		{
		  take = 0;
		  break;
		}
	      if (*ip == 'q')
		{
		  printf("Abort.\n");
		  exit(1);
		}
	    }
	  if (!take)
	    continue;
	  solver_take_solution(solv, problem, take, &job);
	}
    }

  trans = solver_create_transaction(solv);
  if (!trans->steps.count)
    {
      printf("Nothing to do.\n");
      transaction_free(trans);
      solver_free(solv);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(1);
    }

  /* display transaction to the user and ask for confirmation */
  printf("\n");
  printf("Transaction summary:\n\n");
  transaction_print(trans);
#if defined(SUSE)
  showdiskusagechanges(trans);
#endif
  printf("install size change: %d K\n", transaction_calc_installsizechange(trans));
  printf("\n");

  acnt = solver_alternatives_count(solv);
  if (acnt)
    {
      if (acnt == 1)
        printf("Have one alternative:\n");
      else
        printf("Have %d alternatives:\n", acnt);
      for (i = 1; i <= acnt; i++)
	{
	  Id id, from;
	  int atype = solver_get_alternative(solv, i, &id, &from, 0, 0, 0);
	  printf("  - %s\n", solver_alternative2str(solv, atype, id, from));
	}
      printf("\n");
      answer = yesno("OK to continue (y/n/a)? ", 'a');
    }
  else
    answer = yesno("OK to continue (y/n)? ", 0);
  if (answer == 'a')
    {
      Queue choicesq;
      Queue answerq;
      Id id, from, chosen;
      int j;

      queue_init(&choicesq);
      queue_init(&answerq);
      for (i = 1; i <= acnt; i++)
	{
	  int atype = solver_get_alternative(solv, i, &id, &from, &chosen, &choicesq, 0);
	  printf("\n%s\n", solver_alternative2str(solv, atype, id, from));
	  for (j = 0; j < choicesq.count; j++)
	    {
	      Id p = choicesq.elements[j];
	      if (p < 0)
		p = -p;
	      queue_push(&answerq, p);
	      printf("%6d: %s\n", answerq.count, pool_solvid2str(pool, p));
	    }
	}
      queue_free(&choicesq);
      printf("\n");
      for (;;)
	{
	  char inbuf[128], *ip;
	  int neg = 0;
	  printf("OK to continue (y/n), or number to change alternative: ");
	  fflush(stdout);
	  *inbuf = 0;
	  if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
	    {
	      printf("Abort.\n");
	      exit(1);
	    }
	  while (*ip == ' ' || *ip == '\t')
	    ip++;
	  if (*ip == '-' && ip[1] >= '0' && ip[1] <= '9')
	    {
	      neg = 1;
	      ip++;
	    }
	  if (*ip >= '0' && *ip <= '9')
	    {
	      int take = atoi(ip);
	      if (take > 0 && take <= answerq.count)
		{
		  Id p = answerq.elements[take - 1];
		  queue_free(&answerq);
		  queue_push2(&job, (neg ? SOLVER_DISFAVOR : SOLVER_FAVOR) | SOLVER_SOLVABLE_NAME, pool->solvables[p].name);
		  solver_free(solv);
		  solv = 0;
		  goto rerunsolver;
		  break;
		}
	    }
	  if (*ip == 'n' || *ip == 'y')
	    {
	      answer = *ip == 'n' ? 0 : *ip;
	      break;
	    }
	}
      queue_free(&answerq);
    }
  if (!answer)
    {
      printf("Abort.\n");
      transaction_free(trans);
      solver_free(solv);
      queue_free(&job);
      pool_free(pool);
      free_repoinfos(repoinfos, nrepoinfos);
      solv_free(commandlinepkgs);
      exit(1);
    }

  /* download all new packages */
  queue_init(&checkq);
  newpkgs = transaction_installedresult(trans, &checkq);
  newpkgsfps = 0;
  if (newpkgs)
    {
      int downloadsize = 0;
      for (i = 0; i < newpkgs; i++)
	{
	  Solvable *s;

	  p = checkq.elements[i];
	  s = pool_id2solvable(pool, p);
	  downloadsize += solvable_lookup_sizek(s, SOLVABLE_DOWNLOADSIZE, 0);
	}
      printf("Downloading %d packages, %d K\n", newpkgs, downloadsize);
      newpkgsfps = solv_calloc(newpkgs, sizeof(*newpkgsfps));
      for (i = 0; i < newpkgs; i++)
	{
	  const char *loc;
	  Solvable *s;
	  struct repoinfo *cinfo;

	  p = checkq.elements[i];
	  s = pool_id2solvable(pool, p);
	  if (s->repo == commandlinerepo)
	    {
	      loc = solvable_lookup_location(s, 0);
	      if (!loc)
		continue;
	      if (!(newpkgsfps[i] = fopen(loc, "r")))
		{
		  perror(loc);
		  exit(1);
		}
	      putchar('.');
	      continue;
	    }
	  cinfo = s->repo->appdata;
	  if (!cinfo || cinfo->type == TYPE_INSTALLED)
	    {
	      printf("%s: no repository information\n", s->repo->name);
	      exit(1);
	    }
	  loc = solvable_lookup_location(s, 0);
	  if (!loc)
	     continue;	/* pseudo package? */
#if defined(ENABLE_RPMDB)
	  if (pool->installed && pool->installed->nsolvables)
	    {
	      if ((newpkgsfps[i] = trydeltadownload(s, loc)) != 0)
		{
		  putchar('d');
		  fflush(stdout);
		  continue;		/* delta worked! */
		}
	    }
#endif
	  if ((newpkgsfps[i] = downloadpackage(s, loc)) == 0)
	    {
	      printf("\n%s: %s not found in repository\n", s->repo->name, loc);
	      exit(1);
	    }
	  putchar('.');
	  fflush(stdout);
	}
      putchar('\n');
    }

#if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA))
  /* check for file conflicts */
  if (newpkgs)
    {
      Queue conflicts;
      queue_init(&conflicts);
      if (checkfileconflicts(pool, &checkq, newpkgs, newpkgsfps, &conflicts))
	{
	  if (yesno("Re-run solver (y/n/q)? ", 0))
	    {
	      for (i = 0; i < newpkgs; i++)
		if (newpkgsfps[i])
		  fclose(newpkgsfps[i]);
	      newpkgsfps = solv_free(newpkgsfps);
	      solver_free(solv);
	      solv = 0;
	      pool_add_fileconflicts_deps(pool, &conflicts);
	      queue_free(&conflicts);
	      goto rerunsolver;
	    }
	}
      queue_free(&conflicts);
    }
#endif

  /* and finally commit the transaction */
  printf("Committing transaction:\n\n");
  transaction_order(trans, 0);
  for (i = 0; i < trans->steps.count; i++)
    {
      int j;
      FILE *fp;
      Id type;

      p = trans->steps.elements[i];
      type = transaction_type(trans, p, SOLVER_TRANSACTION_RPM_ONLY);
      switch(type)
	{
	case SOLVER_TRANSACTION_ERASE:
	  printf("erase %s\n", pool_solvid2str(pool, p));
	  commit_transactionelement(pool, type, p, 0);
	  break;
	case SOLVER_TRANSACTION_INSTALL:
	case SOLVER_TRANSACTION_MULTIINSTALL:
	  printf("install %s\n", pool_solvid2str(pool, p));
	  for (j = 0; j < newpkgs; j++)
	    if (checkq.elements[j] == p)
	      break;
	  fp = j < newpkgs ? newpkgsfps[j] : 0;
	  if (!fp)
	    continue;
	  commit_transactionelement(pool, type, p, fp);
	  fclose(fp);
	  newpkgsfps[j] = 0;
	  break;
	default:
	  break;
	}
    }

  for (i = 0; i < newpkgs; i++)
    if (newpkgsfps[i])
      fclose(newpkgsfps[i]);
  solv_free(newpkgsfps);
  queue_free(&checkq);
  transaction_free(trans);
  solver_free(solv);
  queue_free(&job);
  pool_free(pool);
  free_repoinfos(repoinfos, nrepoinfos);
  solv_free(commandlinepkgs);
  exit(0);
}
Esempio n. 9
0
static int gettarhead(struct tarhead *th)
{
  int l, type;
  long long length;

  th->path = solv_free(th->path);
  th->ispax = 0;
  th->type = 0;
  th->length = 0;
  th->off = 0;
  th->end = 0;
  if (th->eof)
    return 0;
  for (;;)
    {
      int r = readblock(th->fp, th->blk);
      if (r)
	{
	  if (feof(th->fp))
	    {
	      th->eof = 1;
	      return 0;
	    }
	  return -1;
	}
      if (th->blk[0] == 0)
	{
          th->eof = 1;
	  return 0;
	}
      length = parsenum(th->blk + 124, 12);
      if (length < 0)
	return -1;
      type = 0;
      switch (th->blk[156])
	{
	case 'S': case '0':
	  type = 1;	/* file */
	  break;
	case '1':
	  /* hard link, special length magic... */
	  if (!th->ispax)
	    length = 0;
	  break;
	case '5':
	  type = 2;	/* dir */
	  break;
	case '2': case '3': case '4': case '6':
	  length = 0;
	  break;
	case 'X': case 'x': case 'L':
	  {
	    char *data, *pp;
	    if (length < 1 || length >= 1024 * 1024)
	      return -1;
	    l = length;
	    data = pp = solv_malloc(l + 512);
	    for (; l > 0; l -= 512, pp += 512)
	      if (readblock(th->fp, (unsigned char *)pp))
	        {
		  solv_free(data);
		  return -1;
	        }
	    type = 3;		/* extension */
	    if (th->blk[156] == 'L')
	      {
	        solv_free(th->path);
	        th->path = data;
	        length = 0;
		break;
	      }
	    pp = data;
	    while (length > 0)
	      {
		int ll = 0;
		int l;
		for (l = 0; l < length && pp[l] >= '0' && pp[l] <= '9'; l++)
		  ll = ll * 10 + (pp[l] - '0');
		if (l == length || pp[l] != ' ' || ll < 1 || ll > length || pp[ll - 1] != '\n')
		  {
		    solv_free(data);
		    return -1;
		  }
		length -= ll;
		pp += l + 1;
		ll -= l + 1;
		pp[ll - 1] = 0;
		if (!strncmp(pp, "path=", 5))
		  {
		    solv_free(th->path);
		    th->path = solv_strdup(pp + 5);
		  }
		pp += ll;
	      }
	    solv_free(data);
	    th->ispax = 1;
	    length = 0;
	    break;
	  }
	default:
	  type = 3;	/* extension */
	  break;
	}
      if ((type == 1 || type == 2) && !th->path)
	{
	  char path[157];
	  memcpy(path, th->blk, 156);
	  path[156] = 0;
	  if (!memcmp(th->blk + 257, "ustar\0\060\060", 8) && !th->path && th->blk[345])
	    {
	      /* POSIX ustar with prefix */
	      char prefix[156];
	      memcpy(prefix, th->blk + 345, 155);
	      prefix[155] = 0;
	      l = strlen(prefix);
	      if (l && prefix[l - 1] == '/')
		prefix[l - 1] = 0;
	      th->path = solv_dupjoin(prefix, "/", path);
	    }
	  else
	    th->path = solv_dupjoin(path, 0, 0);
	}
      if (type == 1 || type == 2)
	{
	  l = strlen(th->path);
	  if (l && th->path[l - 1] == '/')
	    {
	      if (l > 1)
		th->path[l - 1] = 0;
	      type = 2;
	    }
	}
      if (type != 3)
	break;
      while (length > 0)
	{
	  r = readblock(th->fp, th->blk);
	  if (r)
	    return r;
	  length -= 512;
	}
    }
  th->type = type;
  th->length = length;
  return 1;
}