1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
|
#!/usr/bin/tclsh
package require solv
package require inifile
package require fileutil
set reposdir /etc/zypp/repos.d
### some helpers
proc fileno {file} {
if [regexp -- {^file(\d+)$} $file match fd] {
return $fd
}
error "file not open"
}
set ::globalarray_cnt 0
proc globalarray {} {
set name "::globalarray_[incr ::globalarray_cnt]"
array set $name [list varName $name]
return $name
}
### generic repo handling (cache reading/writing)
proc repo_calc_cookie_file {selfName filename} {
upvar $selfName self
set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256]
$chksum add "1.1"
$chksum add_stat $filename
return [$chksum raw]
}
proc repo_calc_cookie_fp {selfName fp} {
upvar $selfName self
set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256]
$chksum add "1.1"
$chksum add_fp $fp
return [$chksum raw]
}
proc repo_calc_cookie_ext {selfName f cookie} {
upvar $selfName self
set chksum [solv::new_Chksum $solv::REPOKEY_TYPE_SHA256]
$chksum add "1.1"
$chksum add $cookie
$chksum add_fstat [$f fileno]
return [$chksum raw]
}
proc repo_cachepath {selfName {ext "-"}} {
upvar $selfName self
regsub {^\.} $self(name) _ path
if {$ext ne "-"} {
set path "${path}_$ext.solvx"
} else {
set path "${path}.solv"
}
regsub -all / $path _ path
return "/var/cache/solv/$path"
}
proc repo_generic_load {selfName pool} {
upvar $selfName self
set handle [ $pool add_repo $self(name) ]
set self(handle) $handle
$handle configure -priority [expr 99 - $self(priority)] -appdata $self(varName)
set dorefresh $self(autorefresh)
set metadata_expire $self(metadata_expire)
catch {
if {$metadata_expire == -1 || [clock seconds] - [file mtime [repo_cachepath self]] < $metadata_expire} {
set dorefresh 0
}
}
set self(cookie) {}
set self(extcookie) {}
if { !$dorefresh && [repo_usecachedrepo self] } {
puts "repo $self(name): cached"
return 1
}
return 0
}
proc repo_free_handle {selfName} {
upvar $selfName self
set handle $self(handle)
unset self(handle)
$handle free 1
}
proc repo_usecachedrepo {selfName {ext "-"} {mark 0}} {
upvar $selfName self
set repopath [repo_cachepath self $ext]
set code [catch {
set f [open $repopath "rb"]
seek $f -32 end
set fcookie [read $f 32]
set cookie [expr {$ext eq "-" ? $self(cookie) : $self(extcookie)}]
if {$cookie ne {} && $cookie ne $fcookie} {
close $f
return 0
}
set fextcookie {}
if {$ext eq "-" && $self(type) ne "system"} {
seek $f -64 end
set fextcookie [read $f 32]
}
seek $f 0 start
set ff [solv::xfopen_fd {} [fileno $f]]
close $f
set flags 0
if {$ext ne "-"} {
set flags [expr $solv::Repo_REPO_USE_LOADING | $solv::Repo_REPO_EXTEND_SOLVABLES]
if {$ext ne "DL"} {
set flags [expr $flags | $solv::Repo_REPO_LOCALPOOL]
}
}
if {! [$self(handle) add_solv $ff $flags]} {
$ff close
return 0
}
$ff close
if {$self(type) ne "system" && $ext eq "-"} {
set self(cookie) $fcookie
set self(extcookie) $fextcookie
}
if {$mark} {
catch {
::fileutil::touch -c -m -t [clock seconds] $repopath
}
}
return 1
} res]
return [expr {$code == 2 ? $res : 0}]
}
proc repo_writecachedrepo {selfName {ext "-"} {repodata "NULL"}} {
upvar $selfName self
if [info exists self(incomplete)] {
return
}
file mkdir "/var/cache/solv"
::fileutil::tempdir "/var/cache/solv"
set tempfilename [::fileutil::tempfile ".newsolv-"]
::fileutil::tempdirReset
set f [solv::xfopen $tempfilename "w+"]
file attributes $tempfilename -permissions 0444
if {$repodata eq {NULL}} {
$self(handle) write $f
} else {
$repodata write $f
}
$f flush
if {$self(type) ne "system" && $ext eq "-"} {
if {$self(extcookie) eq {}} {
set self(extcookie) [repo_calc_cookie_ext self $f $self(cookie)]
}
$f write $self(extcookie)
}
$f write [expr {$ext eq "-" ? $self(cookie) : $self(extcookie)}]
$f close
file rename -force -- $tempfilename [repo_cachepath self $ext]
}
proc repo_download {selfName file uncompress chksum {markincomplete 0}} {
upvar $selfName self
regsub {/$} $self(baseurl) {} url
set url "$url/$file"
set tempfilename [::fileutil::tempfile]
set f [open $tempfilename rb+]
file delete -- $tempfilename
if [catch {
exec -ignorestderr -- curl -f -s -L $url ">@$f"
}] {
seek $f 0 end
if {($chksum ne "" && $chksum ne "NULL") || [tell $f] != 0} {
puts "$file: download error"
}
close $f
return {NULL}
}
seek $f 0 start
if {$chksum ne "" && $chksum ne "NULL"} {
set fchksum [solv::new_Chksum [$chksum cget -type]]
if {$fchksum eq "" || $fchksum eq "NULL"} {
puts "$file: unknown checksum type"
if {$markincomplete} {
set self(incomplete) 1
}
close $f
return {NULL}
}
$fchksum add_fd [fileno $f]
if {[$fchksum != $chksum]} {
puts "$file: checksum mismatch"
if {$markincomplete} {
set self(incomplete) 1
}
close $f
return {NULL}
}
}
set ff [solv::xfopen_fd [expr {$uncompress ? $file : ""}] [fileno $f]]
close $f
return $ff
}
proc repo_generic_add_ext_keys {selfName ext repodata h} {
upvar $selfName self
if {$ext eq "DL"} {
$repodata add_idarray $h $solv::REPOSITORY_KEYS $solv::REPOSITORY_DELTAINFO
$repodata add_idarray $h $solv::REPOSITORY_KEYS $solv::REPOKEY_TYPE_FLEXARRAY
} elseif {$ext eq "DU"} {
$repodata add_idarray $h $solv::REPOSITORY_KEYS $solv::SOLVABLE_DISKUSAGE
$repodata add_idarray $h $solv::REPOSITORY_KEYS $solv::REPOKEY_TYPE_DIRNUMNUMARRAY
} elseif {$ext eq "FL"} {
$repodata add_idarray $h $solv::REPOSITORY_KEYS $solv::SOLVABLE_FILELIST
$repodata add_idarray $h $solv::REPOSITORY_KEYS $solv::REPOKEY_TYPE_DIRSTRARRAY
}
}
### system
proc repo_system_load {selfName pool} {
upvar $selfName self
set handle [ $pool add_repo $self(name) ]
set self(handle) $handle
$handle configure -appdata $self(varName)
$pool configure -installed $handle
puts -nonewline "rpm database: "
set self(cookie) [repo_calc_cookie_file self "/var/lib/rpm/Packages"]
if [repo_usecachedrepo self] {
puts "cached"
return 1
}
puts "reading"
set f [solv::xfopen [repo_cachepath self]]
$handle add_rpmdb_reffp $f $solv::Repo_REPO_REUSE_REPODATA
repo_writecachedrepo self
}
### repomd
proc repo_repomd_add_ext {selfName repodata what ext} {
upvar $selfName self
set where [repo_repomd_find self $what]
if {$where eq {}} {
return
}
set h [$repodata new_handle]
$repodata set_poolstr $h $solv::REPOSITORY_REPOMD_TYPE $what
$repodata set_str $h $solv::REPOSITORY_REPOMD_LOCATION [lindex $where 0]
$repodata set_checksum $h $solv::REPOSITORY_REPOMD_CHECKSUM [lindex $where 1]
repo_generic_add_ext_keys self $ext $repodata $h
$repodata add_flexarray $solv::SOLVID_META $solv::REPOSITORY_EXTERNAL $h
}
proc repo_repomd_add_exts {selfName} {
upvar $selfName self
set repodata [$self(handle) add_repodata 0]
$repodata extend_to_repo
repo_repomd_add_ext self $repodata "filelists" "FL"
$repodata internalize
}
proc repo_repomd_find {selfName what} {
upvar $selfName self
set di [$self(handle) Dataiterator_meta $solv::REPOSITORY_REPOMD_TYPE $what $solv::Dataiterator_SEARCH_STRING]
$di prepend_keyname $solv::REPOSITORY_REPOMD
solv::iter d $di {
set dp [$d parentpos]
set filename [$dp lookup_str $solv::REPOSITORY_REPOMD_LOCATION]
set checksum [$dp lookup_checksum $solv::REPOSITORY_REPOMD_CHECKSUM]
if {$filename ne "" && $checksum eq "NULL"} {
puts "no $filename file checksum"
} elseif {$filename ne ""} {
return [list $filename $checksum]
}
}
return {}
}
proc repo_repomd_load {selfName pool} {
upvar $selfName self
if [repo_generic_load self $pool] {
return 1
}
puts -nonewline "rpmmd repo '$self(name)': "
set f [repo_download self {repodata/repomd.xml} 0 {}]
if {$f eq {NULL}} {
puts "no repomd.xml file, skipped"
repo_free_handle self
return 0
}
set self(cookie) [repo_calc_cookie_fp self $f]
if [repo_usecachedrepo self "-" 1] {
puts "cached"
return 1
}
set handle $self(handle)
$handle add_repomdxml $f
puts "fetching"
set primary [repo_repomd_find self primary]
if {$primary ne {}} {
set f [repo_download self [lindex $primary 0] 1 [lindex $primary 1] 1]
if {$f ne {NULL}} {
$handle add_rpmmd $f {}
$f close
}
if [info exists self(incomplete)] {
return 0
}
}
set updateinfo [repo_repomd_find self primary]
if {$updateinfo ne {}} {
set f [repo_download self [lindex $updateinfo 0] 1 [lindex $updateinfo 1] 1]
if {$f ne {NULL}} {
$handle add_updateinfoxml $f
$f close
}
}
repo_repomd_add_exts self
repo_writecachedrepo self
$self(handle) create_stubs
return 1
}
proc repo_repomd_packagespath {selfName} {
return ""
}
proc repo_repomd_load_ext {selfName repodata} {
upvar $selfName self
switch -- [$repodata lookup_str $solv::SOLVID_META $solv::REPOSITORY_REPOMD_TYPE] {
"deltainfo" {
set ext DL
}
"filelists" {
set ext FL
}
default {
return 0
}
}
puts -nonewline "\[$self(name):$ext: "
flush stdout
if [repo_usecachedrepo self $ext] {
puts "cached]"
return 1
}
puts "fetching]"
set handle $self(handle)
set filename [$repodata lookup_str $solv::SOLVID_META $solv::REPOSITORY_REPOMD_LOCATION]
set filechecksum [$repodata lookup_checksum $solv::SOLVID_META $solv::REPOSITORY_REPOMD_CHECKSUM]
set f [repo_download self $filename 1 $filechecksum]
if {$f eq {NULL}} {
return 0
}
if {$ext eq "FL"} {
$handle add_rpmmd $f "FL" [ expr $solv::Repo_REPO_USE_LOADING | $solv::Repo_REPO_EXTEND_SOLVABLES | $solv::Repo_REPO_LOCALPOOL]
}
$f close
repo_writecachedrepo self $ext $repodata
return 1
}
### susetags
proc repo_susetags_add_ext {selfName repodata what ext} {
upvar $selfName self
set where [repo_susetags_find self $what]
if {$where eq {}} {
return
}
set h [$repodata new_handle]
$repodata set_str $h $solv::SUSETAGS_FILE_NAME [lindex $where 0]
$repodata set_checksum $h $solv::SUSETAGS_FILE_CHECKSUM [lindex $where 1]
repo_generic_add_ext_keys self $ext $repodata $h
$repodata add_flexarray $solv::SOLVID_META $solv::REPOSITORY_EXTERNAL $h
}
proc repo_susetags_add_exts {selfName} {
upvar $selfName self
set repodata [$self(handle) add_repodata 0]
$repodata extend_to_repo
repo_susetags_add_ext self $repodata "packages.FL" "FL"
repo_susetags_add_ext self $repodata "packages.FL.gz" "FL"
$repodata internalize
}
proc repo_susetags_find {selfName what} {
upvar $selfName self
set di [$self(handle) Dataiterator_meta $solv::SUSETAGS_FILE_NAME $what $solv::Dataiterator_SEARCH_STRING]
$di prepend_keyname $solv::SUSETAGS_FILE
solv::iter d $di {
set dp [$d parentpos]
set checksum [$dp lookup_checksum $solv::SUSETAGS_FILE_CHECKSUM]
return [list $what $checksum]
}
return {}
}
proc repo_susetags_load {selfName pool} {
upvar $selfName self
if [repo_generic_load self $pool] {
return 1
}
puts -nonewline "susetags repo '$self(name)': "
set f [repo_download self {content} 0 {}]
if {$f eq {NULL}} {
puts "no content file, skipped"
repo_free_handle self
return 0
}
set self(cookie) [repo_calc_cookie_fp self $f]
if [repo_usecachedrepo self "-" 1] {
puts "cached"
return 1
}
set handle $self(handle)
$handle add_content $f
puts "fetching"
set defvendorid [[$handle cget -meta] lookup_id $solv::SUSETAGS_DEFAULTVENDOR]
set descrdir [[$handle cget -meta] lookup_str $solv::SUSETAGS_DESCRDIR]
if {$descrdir eq {NULL}} {
set descrdir "suse/setup/descr"
}
set packages [repo_susetags_find self "packages.gz"]
if {$packages eq {}} {
set packages [repo_susetags_find self "packages"]
}
if {$packages ne {}} {
set f [repo_download self "$descrdir/[lindex $packages 0]" 1 [lindex $packages 1] 1]
if {$f ne {NULL}} {
$handle add_susetags $f $defvendorid {} [expr $solv::Repo_REPO_NO_INTERNALIZE | $solv::Repo_SUSETAGS_RECORD_SHARES]
$f close
set packages [repo_susetags_find self "packages.en.gz"]
if {$packages eq {}} {
set packages [repo_susetags_find self "packages.en"]
}
if {$packages ne {}} {
set f [repo_download self "$descrdir/[lindex $packages 0]" 1 [lindex $packages 1] 1]
if {$f ne {NULL}} {
$handle add_susetags $f $defvendorid {} [expr $solv::Repo_REPO_NO_INTERNALIZE | $solv::Repo_REPO_REUSE_REPODATA | $solv::Repo_REPO_EXTEND_SOLVABLES ]
$f close
}
}
$handle internalize
}
}
repo_susetags_add_exts self
repo_writecachedrepo self
$self(handle) create_stubs
return 1
}
proc repo_susetags_packagespath {selfName} {
upvar $selfName self
set datadir [[$self(handle) cget -meta] lookup_str $solv::SUSETAGS_DATADIR]
return [expr {$datadir ne {} ? "$datadir/" : "suse/"}]
}
proc repo_susetags_load_ext {selfName repodata} {
upvar $selfName self
set filename [$repodata lookup_str $solv::SOLVID_META $solv::SUSETAGS_FILE_NAME]
set ext [string range $filename 9 10]
puts -nonewline "\[$self(name):$ext: "
flush stdout
if [repo_usecachedrepo self $ext] {
puts "cached]"
return 1
}
puts "fetching]"
set handle $self(handle)
set defvendorid [[$handle cget -meta] lookup_id $solv::SUSETAGS_DEFAULTVENDOR]
set descrdir [[$handle cget -meta] lookup_str $solv::SUSETAGS_DESCRDIR]
if {$descrdir eq {NULL}} {
set descrdir "suse/setup/descr"
}
set filechecksum [$repodata lookup_checksum $solv::SOLVID_META $solv::SUSETAGS_FILE_CHECKSUM]
set f [repo_download self "$descrdir/$filename" 1 $filechecksum]
if {$f eq {NULL}} {
return 0
}
set flags [expr $solv::Repo_REPO_USE_LOADING | $solv::Repo_REPO_EXTEND_SOLVABLES]
if {$ext ne "DL"} {
set flags [expr $flags | $solv::Repo_REPO_LOCALPOOL]
}
$handle add_susetags $f $defvendorid $ext $flags
$f close
repo_writecachedrepo self $ext $repodata
return 1
}
### unknown
proc repo_unknown_load {selfName pool} {
upvar $selfName self
puts "unsupported repo '$self(name)': skipped"
return 0
}
### poor man's OO
proc repo_load {selfName pool} {
upvar $selfName self
"repo_$self(type)_load" self $pool
}
proc repo_packagespath {selfName} {
upvar $selfName self
"repo_$self(type)_packagespath" self
}
proc repo_load_ext {selfName repodata} {
upvar $selfName self
"repo_$self(type)_load_ext" self $repodata
}
###
proc load_stub {repodata} {
set code [catch {
upvar #0 [[$repodata cget -repo] cget -appdata] repo
if [info exists repo(handle)] {
return [repo_load_ext repo $repodata]
}
return 0
} res]
if {$code == 2} {
return $res
}
puts stderr $res
return 0
}
###
set repoNames {}
foreach reponame [lsort [glob -nocomplain -directory $reposdir *.repo]] {
set ini [::ini::open $reponame r]
foreach alias [::ini::sections $ini] {
upvar #0 [globalarray] repo
array set repo {enabled 0 priority 99 autorefresh 1 type rpm-md metadata_expire 900}
array set repo [::ini::get $ini $alias]
set repo(name) $alias
switch -exact -- $repo(type) {
rpm-md { set repo(type) repomd }
yast2 { set repo(type) susetags }
default { set repo(type) unknown }
}
lappend repoNames $repo(varName)
}
::ini::close $ini
}
set pool [solv::new_Pool]
$pool setarch
$pool set_loadcallback load_stub
upvar #0 [globalarray] sysrepo
array set sysrepo [list name {@System} type system]
repo_load sysrepo $pool
foreach repoName $repoNames {
upvar 0 $repoName repo
if {$repo(enabled)} {
repo_load repo $pool
}
}
set cmd [lindex $::argv 0]
set ::argv [lreplace $::argv 0 0]
array set cmdabbrev [ list \
in install \
rm erase \
ls list \
ve verify \
se search \
]
if [info exists cmdabbrev($cmd)] {
set cmd $cmdabbrev($cmd)
}
if {$cmd eq "search"} {
set arg [lindex $::argv 0]
$pool createwhatprovides
set sel [$pool Selection]
set di [$pool Dataiterator $solv::SOLVABLE_NAME $arg [ expr $solv::Dataiterator_SEARCH_SUBSTRING | $solv::Dataiterator_SEARCH_NOCASE ]]
solv::iter d $di {
$sel add_raw $solv::Job_SOLVER_SOLVABLE [$d cget -solvid]
}
foreach s [$sel solvables] {
puts [format { - %s [%s]: %s} [$s str] [[$s cget -repo] cget -name] [$s lookup_str $solv::SOLVABLE_SUMMARY]]
}
exit
}
$pool addfileprovides
$pool createwhatprovides
array set cmdactionmap [ list \
install $solv::Job_SOLVER_INSTALL \
erase $solv::Job_SOLVER_ERASE \
up $solv::Job_SOLVER_UPDATE \
dup $solv::Job_SOLVER_DISTUPGRADE \
verify $solv::Job_SOLVER_VERIFY \
list 0 \
info 0 \
]
set jobs {}
foreach arg $::argv {
set flags [expr $solv::Selection_SELECTION_NAME | $solv::Selection_SELECTION_PROVIDES | $solv::Selection_SELECTION_GLOB | \
$solv::Selection_SELECTION_CANON | $solv::Selection_SELECTION_DOTARCH | $solv::Selection_SELECTION_REL ]
switch -glob -- $arg {
"/*" {
set flags [expr $flags | $solv::Selection_SELECTION_FILELIST ]
if {$cmd eq "erase"} {
set flags [expr $flags | $solv::Selection_SELECTION_INSTALLED_ONLY ]
}
}
}
set sel [$pool select $arg $flags]
if [$sel isempty] {
set sel [$pool select $arg [expr $flags | $solv::Selection_SELECTION_NOCASE]]
if {![$sel isempty]} {
puts "\[ignoring case for '$arg']"
}
}
if [$sel isempty] {
puts "nothing matches '$arg'"
exit 1
}
if {[$sel cget -flags] & $solv::Selection_SELECTION_FILELIST} {
puts "\[using file list match for '$arg']"
}
if {[$sel cget -flags] & $solv::Selection_SELECTION_PROVIDES} {
puts "\[using capability match for '$arg']"
}
lappend jobs {*}[$sel jobs $cmdactionmap($cmd)]
}
if {$jobs eq {} && ($cmd eq "up" || $cmd eq "dup" || $cmd eq "verify") } {
set sel [$pool Selection_all]
lappend jobs {*}[$sel jobs $cmdactionmap($cmd)]
}
if {$jobs eq {}} {
puts "no package matched."
exit 1
}
if {$cmd eq "list" || $cmd eq "info"} {
foreach job $jobs {
foreach s [$job solvables] {
if {$cmd eq "info"} {
puts [format {Name: %s} [$s str]]
puts [format {Repo: %s} [[$s cget -repo] cget -name]]
puts [format {Summary: %s} [$s lookup_str $solv::SOLVABLE_SUMMARY]]
set str [$s lookup_str $solv::SOLVABLE_URL]
if {$str ne {}} {
puts [format {Url: %s} $str]
}
set str [$s lookup_str $solv::SOLVABLE_LICENSE]
if {$str ne {}} {
puts [format {License %s} $str]
}
puts [format {Description: %s} [$s lookup_str $solv::SOLVABLE_DESCRIPTION]]
puts {}
} else {
puts [format { - %s [%s]} [$s str] [[$s cget -repo] cget -name]]
puts [format { %s} [$s lookup_str $solv::SOLVABLE_SUMMARY]]
}
}
}
exit
}
#$pool set_debuglevel 1
set solver [$pool Solver]
$solver set_flag $solv::Solver_SOLVER_FLAG_SPLITPROVIDES 1
if {$cmd eq "erase"} {
$solver set_flag $solv::Solver_SOLVER_FLAG_ALLOW_UNINSTALL 1
}
set problems [$solver solve $jobs]
if {$problems ne {}} {
set pcnt 1
foreach problem $problems {
puts [format {Problem %d/%d:} $pcnt [llength $problems]]
puts [$problem str]
incr pcnt
}
exit 1
}
set trans [$solver transaction]
if [$trans isempty] {
puts "Nothing to do."
exit
}
puts {}
puts "Transaction summary:"
puts {}
foreach cl [$trans classify [expr $solv::Transaction_SOLVER_TRANSACTION_SHOW_OBSOLETES | $solv::Transaction_SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE]] {
switch -- [$cl cget -type] \
$solv::Transaction_SOLVER_TRANSACTION_ERASE {
puts [format {%d erased packages:} [$cl cget -count]]
} \
$solv::Transaction_SOLVER_TRANSACTION_INSTALL {
puts [format {%d installed packages:} [$cl cget -count]]
} \
$solv::Transaction_SOLVER_TRANSACTION_REINSTALLED {
puts [format {%d reinstalled packages:} [$cl cget -count]]
} \
$solv::Transaction_SOLVER_TRANSACTION_DOWNGRADED {
puts [format {%d downgraded packages:} [$cl cget -count]]
} \
$solv::Transaction_SOLVER_TRANSACTION_CHANGED {
puts [format {%d changed packages:} [$cl cget -count]]
} \
$solv::Transaction_SOLVER_TRANSACTION_UPGRADED {
puts [format {%d upgraded packages:} [$cl cget -count]]
} \
$solv::Transaction_SOLVER_TRANSACTION_VENDORCHANGE {
puts [format {%d vendor changes from '%s' to '%s':} [$cl cget -count] [$cl cget -fromstr] [$cl cget -tostr]]
} \
$solv::Transaction_SOLVER_TRANSACTION_ARCHCHANGE {
puts [format {%d archchanges from '%s' to '%s':} [$cl cget -count] [$cl cget -fromstr] [$cl cget -tostr]]
} \
default continue
foreach p [$cl solvables] {
set cltype [$cl cget -type]
if {$cltype == $solv::Transaction_SOLVER_TRANSACTION_UPGRADED || $cltype ==$solv::Transaction_SOLVER_TRANSACTION_DOWNGRADED} {
set op [$trans othersolvable $p]
puts [format { - %s -> %s} [$p str] [$op str]]
} else {
puts [format { - %s} [$p str]]
}
}
puts {}
}
puts [format {install size change: %d K} [$trans calc_installsizechange]]
puts {}
while 1 {
puts -nonewline "OK to continue (y/n)? "
flush stdout
set yn [gets stdin]
if {$yn eq "y"} {
break
}
if {$yn eq "n" || $yn eq "q"} {
exit
}
}
set newpkgs [$trans newsolvables]
array set newpkgs_f {}
if {$newpkgs ne {}} {
set downloadsize 0
foreach p $newpkgs {
set downloadsize [expr $downloadsize + [$p lookup_num $solv::SOLVABLE_DOWNLOADSIZE]]
}
puts [format {Downloading %d packages, %d K} [llength $newpkgs] [expr $downloadsize / 1024]]
foreach p $newpkgs {
upvar #0 [[$p cget -repo] cget -appdata] repo
set location [$p lookup_location]
if {$location eq {}} {
continue
}
set location "[repo_packagespath repo][lindex $location 0]"
set checksum [$p lookup_checksum $solv::SOLVABLE_CHECKSUM]
set f [repo_download repo $location 0 $checksum]
set newpkgs_f([$p cget -id]) $f
puts -nonewline "."
flush stdout
}
puts {}
}
puts "Committing transaction:"
$trans order
foreach p [$trans steps] {
set steptype [$trans steptype $p $solv::Transaction_SOLVER_TRANSACTION_RPM_ONLY]
if {$steptype == $solv::Transaction_SOLVER_TRANSACTION_ERASE} {
puts "erase [$p str]"
regsub {^[0-9]+:} [$p cget -evr] {} nvr
set nvr "[$p cget -name]-$nvr.[$p cget -arch]"
exec -ignorestderr -- rpm -e --nodeps --nodigest --nosignature $nvr
} elseif {$steptype == $solv::Transaction_SOLVER_TRANSACTION_INSTALL || $steptype == $solv::Transaction_SOLVER_TRANSACTION_MULTIINSTALL} {
puts "install [$p str]"
set f $newpkgs_f([$p cget -id])
set mode [expr {$steptype == $solv::Transaction_SOLVER_TRANSACTION_INSTALL ? "-U" : "-i"}]
$f cloexec 0
exec -ignorestderr -- rpm $mode --force --nodeps --nodigest --nosignature "/dev/fd/[$f fileno]"
}
}
|