Only mark pacakges for update if there is a newer version available.
12 #include "razor-internal.h"
14 static const char system_repo_filename[] = "system.repo";
15 static const char next_repo_filename[] = "system-next.repo";
16 static const char rawhide_repo_filename[] = "rawhide.repo";
17 static const char updated_repo_filename[] = "system-updated.repo";
18 static const char razor_root_path[] = "/var/lib/razor";
19 static const char root[] = "install";
20 static const char *repo_filename = system_repo_filename;
23 command_list(int argc, const char *argv[])
25 struct razor_set *set;
26 struct razor_package_iterator *pi;
27 struct razor_package *package;
28 const char *pattern = argv[0], *name, *version;
30 set = razor_set_open(repo_filename);
31 pi = razor_package_iterator_create(set);
32 while (razor_package_iterator_next(pi, &package, &name, &version)) {
33 if (pattern && fnmatch(pattern, name, 0) != 0)
36 printf("%s-%s\n", name, version);
38 razor_package_iterator_destroy(pi);
39 razor_set_destroy(set);
45 list_properties(const char *package_name,
46 enum razor_property_type required_type)
48 struct razor_set *set;
49 struct razor_property *property;
50 struct razor_package *package;
51 struct razor_property_iterator *pi;
52 const char *name, *version;
53 enum razor_property_type type;
54 enum razor_version_relation relation;
56 set = razor_set_open(repo_filename);
58 package = razor_set_get_package(set, package_name);
62 pi = razor_property_iterator_create(set, package);
63 while (razor_property_iterator_next(pi, &property,
64 &name, &relation, &version,
66 if (type != required_type)
68 if (version[0] == '\0')
71 printf("%s %s %s\n", name,
72 razor_version_relations[relation], version);
74 razor_property_iterator_destroy(pi);
76 razor_set_destroy(set);
82 command_list_requires(int argc, const char *argv[])
84 return list_properties(argv[0], RAZOR_PROPERTY_REQUIRES);
88 command_list_provides(int argc, const char *argv[])
90 return list_properties(argv[0], RAZOR_PROPERTY_PROVIDES);
94 command_list_obsoletes(int argc, const char *argv[])
96 return list_properties(argv[0], RAZOR_PROPERTY_OBSOLETES);
100 command_list_conflicts(int argc, const char *argv[])
102 return list_properties(argv[0], RAZOR_PROPERTY_CONFLICTS);
106 command_list_files(int argc, const char *argv[])
108 struct razor_set *set;
110 set = razor_set_open(repo_filename);
113 razor_set_list_files(set, argv[0]);
114 razor_set_destroy(set);
120 command_list_file_packages(int argc, const char *argv[])
122 struct razor_set *set;
123 struct razor_package_iterator *pi;
124 struct razor_package *package;
125 const char *name, *version;
127 set = razor_set_open(repo_filename);
131 pi = razor_package_iterator_create_for_file(set, argv[0]);
132 while (razor_package_iterator_next(pi, &package, &name, &version))
133 printf("%s-%s\n", name, version);
134 razor_package_iterator_destroy(pi);
136 razor_set_destroy(set);
142 command_list_package_files(int argc, const char *argv[])
144 struct razor_set *set;
146 set = razor_set_open(repo_filename);
149 razor_set_list_package_files(set, argv[0]);
150 razor_set_destroy(set);
156 list_packages_for_property(struct razor_set *set,
157 struct razor_property *property)
159 struct razor_package_iterator *pi;
160 struct razor_package *package;
161 const char *name, *version;
163 pi = razor_package_iterator_create_for_property(set, property);
164 while (razor_package_iterator_next(pi, &package, &name, &version))
165 printf("%s-%s\n", name, version);
166 razor_package_iterator_destroy(pi);
170 list_property_packages(const char *ref_name,
171 const char *ref_version,
172 enum razor_property_type ref_type)
174 struct razor_set *set;
175 struct razor_property *property;
176 struct razor_property_iterator *pi;
177 const char *name, *version;
178 enum razor_property_type type;
179 enum razor_version_relation relation;
181 if (ref_name == NULL)
184 set = razor_set_open(repo_filename);
188 pi = razor_property_iterator_create(set, NULL);
189 while (razor_property_iterator_next(pi, &property,
190 &name, &relation, &version,
192 if (strcmp(ref_name, name) != 0)
194 if (ref_version && relation == RAZOR_VERSION_EQUAL &&
195 strcmp(ref_version, version) != 0)
197 if (ref_type != type)
200 list_packages_for_property(set, property);
202 razor_property_iterator_destroy(pi);
208 command_what_requires(int argc, const char *argv[])
210 return list_property_packages(argv[0], argv[1],
211 RAZOR_PROPERTY_REQUIRES);
215 command_what_provides(int argc, const char *argv[])
217 return list_property_packages(argv[0], argv[1],
218 RAZOR_PROPERTY_PROVIDES);
222 show_progress(void *clientp,
223 double dltotal, double dlnow, double ultotal, double ulnow)
225 const char *file = clientp;
227 if (!dlnow < dltotal)
228 fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
229 file, (int) dlnow / 1024, (int) dltotal / 1024);
231 fprintf(stderr, "\n");
237 download_if_missing(CURL *curl, const char *url, const char *file)
245 curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
246 curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
247 curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
248 curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
250 if (stat(file, &buf) < 0) {
251 fp = fopen(file, "w");
252 snprintf(buffer, sizeof buffer, "%s/%s", url, file);
253 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
254 curl_easy_setopt(curl, CURLOPT_URL, buffer);
255 res = curl_easy_perform(curl);
257 if (res != CURLE_OK) {
258 fprintf(stderr, "curl error: %s\n", error);
267 #define REPO_URL "http://download.fedora.redhat.com" \
268 "/pub/fedora/linux/development/i386/os/repodata"
271 command_import_yum(int argc, const char *argv[])
273 struct razor_set *set;
276 curl = curl_easy_init();
280 if (download_if_missing(curl, REPO_URL, "primary.xml.gz") < 0)
282 if (download_if_missing(curl, REPO_URL, "filelists.xml.gz") < 0)
284 curl_easy_cleanup(curl);
286 set = razor_set_create_from_yum();
289 razor_set_write(set, rawhide_repo_filename);
290 razor_set_destroy(set);
291 printf("wrote %s\n", rawhide_repo_filename);
297 command_import_rpmdb(int argc, const char *argv[])
299 struct razor_set *set;
301 set = razor_set_create_from_rpmdb();
304 razor_set_write(set, repo_filename);
305 razor_set_destroy(set);
306 printf("wrote %s\n", repo_filename);
312 command_validate(int argc, const char *argv[])
314 struct razor_set *set;
316 set = razor_set_open(repo_filename);
319 razor_set_list_unsatisfied(set);
320 razor_set_destroy(set);
326 command_update(int argc, const char *argv[])
328 struct razor_set *set, *upstream;
329 struct razor_transaction *trans;
331 set = razor_set_open(repo_filename);
332 upstream = razor_set_open(rawhide_repo_filename);
333 if (set == NULL || upstream == NULL)
335 trans = razor_transaction_create(set, upstream, argc, argv, 0, NULL);
336 razor_transaction_describe(trans);
340 set = razor_transaction_run(trans);
341 razor_transaction_destroy(trans);
342 razor_set_write(set, updated_repo_filename);
343 razor_set_destroy(set);
344 razor_set_destroy(upstream);
345 printf("wrote system-updated.repo\n");
351 command_remove(int argc, const char *argv[])
353 struct razor_set *set;
354 struct razor_transaction *trans;
356 set = razor_set_open(repo_filename);
359 trans = razor_transaction_create(set, NULL, 0, NULL, argc, argv);
360 razor_transaction_describe(trans);
364 set = razor_transaction_run(trans);
365 razor_transaction_destroy(trans);
366 razor_set_write(set, updated_repo_filename);
367 razor_set_destroy(set);
368 printf("wrote system-updated.repo\n");
374 print_diff(const char *name,
375 const char *old_version, const char *new_version, void *data)
378 printf("removing %s %s\n", name, old_version);
380 printf("install %s %s\n", name, new_version);
384 command_diff(int argc, const char *argv[])
386 struct razor_set *set, *updated;
388 set = razor_set_open(repo_filename);
389 updated = razor_set_open(updated_repo_filename);
390 if (set == NULL || updated == NULL)
393 razor_set_diff(set, updated, print_diff, NULL);
395 razor_set_destroy(set);
396 razor_set_destroy(updated);
402 command_import_rpms(int argc, const char *argv[])
406 struct razor_importer *importer;
407 struct razor_set *set;
408 struct razor_rpm *rpm;
411 const char *dirname = argv[0];
413 if (dirname == NULL) {
414 fprintf(stderr, "usage: razor import-rpms DIR\n");
418 dir = opendir(dirname);
420 fprintf(stderr, "couldn't read dir %s\n", dirname);
424 importer = razor_importer_new();
426 while (de = readdir(dir), de != NULL) {
427 len = strlen(de->d_name);
428 if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
430 snprintf(filename, sizeof filename,
431 "%s/%s", dirname, de->d_name);
432 rpm = razor_rpm_open(filename);
435 "failed to open rpm \"%s\"\n", filename);
438 if (razor_importer_add_rpm(importer, rpm)) {
439 fprintf(stderr, "couldn't import %s\n", filename);
442 razor_rpm_close(rpm);
446 razor_importer_destroy(importer);
450 set = razor_importer_finish(importer);
452 razor_set_write(set, repo_filename);
453 razor_set_destroy(set);
454 printf("wrote %s\n", repo_filename);
459 static struct razor_set *
460 create_set_from_rpms(int argc, const char *argv[])
462 struct razor_importer *importer;
463 struct razor_rpm *rpm;
466 importer = razor_importer_new();
467 for (i = 0; i < argc; i++) {
468 rpm = razor_rpm_open(argv[i]);
471 "failed to open rpm \"%s\"\n", argv[i]);
474 if (razor_importer_add_rpm(importer, rpm)) {
475 fprintf(stderr, "couldn't import %s\n", argv[i]);
478 razor_rpm_close(rpm);
481 return razor_importer_finish(importer);
485 list_packages(int count, struct razor_set *set)
487 struct razor_package_iterator *pi;
488 struct razor_package *package;
489 const char *name, *version;
493 packages = malloc(count * sizeof *packages);
494 pi = razor_package_iterator_create(set);
496 while (razor_package_iterator_next(pi, &package, &name, &version))
497 packages[i++] = strdup(name);
498 razor_package_iterator_destroy(pi);
504 command_install(int argc, const char *argv[])
506 struct razor_set *system, *upstream, *next;
507 struct razor_transaction *trans;
508 struct razor_rpm *rpm;
509 const char *filename;
510 char path[PATH_MAX], new_path[PATH_MAX], **packages;
513 upstream = create_set_from_rpms(argc, argv);
514 snprintf(path, sizeof path,
515 "%s%s/%s", root, razor_root_path, system_repo_filename);
516 system = razor_set_open(path);
517 if (system == NULL) {
518 fprintf(stderr, "couldn't open system package database\n");
522 packages = list_packages(argc, upstream);
523 trans = razor_transaction_create(system, upstream,
524 argc, (const char **)packages,
527 razor_transaction_describe(trans);
531 /* FIXME: Use _finish() convention here? That is, a function
532 * that starts the computation and returns the result while
533 * destroying the transaction. Nice for transient objects
534 * such as the merger and the importer. Should we do that for
535 * transactions too, that is, razor_transaction_finish()? */
536 next = razor_transaction_run(trans);
537 razor_transaction_destroy(trans);
539 /* FIXME: Need razor_set_write_to_fd() so we can open it excl
540 * up front here or fail if it already exists. */
541 snprintf(new_path, sizeof new_path,
542 "%s%s/%s", root, razor_root_path, next_repo_filename);
543 razor_set_write(next, path);
545 razor_set_destroy(next);
546 razor_set_destroy(system);
547 razor_set_destroy(upstream);
549 printf("wrote %s\n", new_path);
551 for (i = 0; i < argc; i++) {
553 rpm = razor_rpm_open(argv[i]);
555 fprintf(stderr, "failed to open rpm %s\n", filename);
558 if (razor_rpm_install(rpm, root) < 0) {
560 "failed to install rpm %s\n", filename);
563 razor_rpm_close(rpm);
567 rename(new_path, path);
568 printf("renamed %s to %s\n", new_path, path);
574 command_init(int argc, const char *argv[])
577 struct razor_set *set;
580 if (stat(root, &buf) < 0) {
581 if (mkdir(root, 0777) < 0) {
583 "could not create install root \"%s\"\n",
587 fprintf(stderr, "created install root \"%s\"\n", root);
588 } else if (!S_ISDIR(buf.st_mode)) {
590 "install root \"%s\" exists, but is not a directory\n",
595 if (razor_create_dir(root, razor_root_path) < 0) {
596 fprintf(stderr, "could not create %s%s\n",
597 root, razor_root_path);
601 set = razor_set_create();
602 snprintf(path, sizeof path, "%s%s/%s",
603 root, razor_root_path, system_repo_filename);
604 if (razor_set_write(set, path) < 0) {
605 fprintf(stderr, "could not write initial package set\n");
608 razor_set_destroy(set);
615 const char *description;
616 int (*func)(int argc, const char *argv[]);
617 } razor_commands[] = {
618 { "list", "list all packages", command_list },
619 { "list-requires", "list all requires for the given package", command_list_requires },
620 { "list-provides", "list all provides for the given package", command_list_provides },
621 { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
622 { "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
623 { "list-files", "list files for package set", command_list_files },
624 { "list-file-packages", "list packages owning file", command_list_file_packages },
625 { "list-package-files", "list files in package", command_list_package_files },
626 { "what-requires", "list the packages that have the given requires", command_what_requires },
627 { "what-provides", "list the packages that have the given provides", command_what_provides },
628 { "import-yum", "import yum metadata files", command_import_yum },
629 { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
630 { "import-rpms", "import rpms from the given directory", command_import_rpms },
631 { "validate", "validate a package set", command_validate },
632 { "update", "update all or specified packages", command_update },
633 { "remove", "remove specified packages", command_remove },
634 { "diff", "show diff between two package sets", command_diff },
635 { "install", "install rpm", command_install },
636 { "init", "init razor root", command_init }
645 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
647 razor_commands[i].name, razor_commands[i].description);
653 main(int argc, const char *argv[])
658 repo = getenv("RAZOR_REPO");
660 repo_filename = repo;
665 for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
666 if (strcmp(razor_commands[i].name, argv[1]) == 0)
667 return razor_commands[i].func(argc - 2, argv + 2);