33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
#
variable loginUrn; # DEFAULT: pkgd_login
if {$force || ![info exists loginUrn]} then {
set loginUrn pkgd_login
}
#
# NOTE: The URN, relative to the base URI, where a single package file
# may be found.
#
variable downloadUrn; # DEFAULT: pkgd_file
if {$force || ![info exists downloadUrn]} then {
|
>
>
>
>
>
>
>
>
>
>
|
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
#
variable loginUrn; # DEFAULT: pkgd_login
if {$force || ![info exists loginUrn]} then {
set loginUrn pkgd_login
}
#
# NOTE: The URN, relative to the base URI, where the list of supported
# platforms for a single package may be found.
#
variable platformsUrn; # DEFAULT: pkgd_platforms
if {$force || ![info exists platformsUrn]} then {
set platformsUrn pkgd_platforms
}
#
# NOTE: The URN, relative to the base URI, where a single package file
# may be found.
#
variable downloadUrn; # DEFAULT: pkgd_file
if {$force || ![info exists downloadUrn]} then {
|
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
variable loginUri; # DEFAULT: ${baseUri}/${loginUrn}?...
if {$force || ![info exists loginUri]} then {
set loginUri [appendArgs \
{${baseUri}/${loginUrn}?} {[uriEscape name $userName]} & \
{[uriEscape password $password]}]
}
#
# NOTE: The URI where a single package file may be found. This file will
# belong to a specific version of one package.
#
variable downloadUri; # DEFAULT: ${baseUri}/${downloadUrn}?...
|
>
>
>
>
>
>
>
>
>
>
|
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
variable loginUri; # DEFAULT: ${baseUri}/${loginUrn}?...
if {$force || ![info exists loginUri]} then {
set loginUri [appendArgs \
{${baseUri}/${loginUrn}?} {[uriEscape name $userName]} & \
{[uriEscape password $password]}]
}
#
# NOTE: The URI where the list of supported platforms for a single
# package may be found.
#
variable platformsUri; # DEFAULT: ${baseUri}/${platformsUrn}?...
if {$force || ![info exists platformsUri]} then {
set platformsUri {${baseUri}/${platformsUrn}?download&name=trunk}
}
#
# NOTE: The URI where a single package file may be found. This file will
# belong to a specific version of one package.
#
variable downloadUri; # DEFAULT: ${baseUri}/${downloadUrn}?...
|
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
|
proc isOpenPgpSignatureFileName { fileName nameOnly } {
if {[string length $fileName] == 0} then {
return false
}
set extension [file extension $fileName]
if {$extension eq ".asc"} then {
if {!$nameOnly && [file exists $fileName]} then {
return [::PackageRepository::isOpenPgpSignature \
[readFile $fileName]]
} else {
return true
}
} else {
|
|
|
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
|
proc isOpenPgpSignatureFileName { fileName nameOnly } {
if {[string length $fileName] == 0} then {
return false
}
set extension [file extension $fileName]
if {$extension eq ".txt" || $extension eq ".asc"} then {
if {!$nameOnly && [file exists $fileName]} then {
return [::PackageRepository::isOpenPgpSignature \
[readFile $fileName]]
} else {
return true
}
} else {
|
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
|
set isClient true
} else {
error "unsupported language"
}
}
#
# NOTE: This procedure verifies the platform specified by the caller. The
# platform argument must be an empty string -OR- one of the literal
# strings "neutral", "win32-arm", "win32-x86", "win64-arm64",
# "win64-ia64", or "win64-x64". An empty string means that the
# associated entity does not require a specific platform. Upon
# failure, a script error will be raised. The return value is
# undefined.
#
proc verifyPlatform { platform varName } {
switch -exact -- $platform {
"" {
#
# NOTE: This platform name is supported; however, the name needs
# to be normalized to "neutral".
#
# TODO: In the future, the empty string may mean "automatically
# detect" the necessary platform instead of always being
# mapped to "neutral".
#
if {[string length $varName] > 0} then {
upvar 1 $varName newPlatform; set newPlatform neutral
}
}
neutral -
win32-arm -
win32-x86 -
win64-arm64 -
win64-ia64 -
win64-x64 {
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
|
>
>
>
>
>
>
>
>
>
|
>
>
>
|
>
|
>
>
>
|
>
|
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
|
set isClient true
} else {
error "unsupported language"
}
}
#
# NOTE: This procedure returns the name of the current platform. There are
# no arguments. An empty string will be returned if the name of the
# current platform cannot be determined for any reason.
#
proc getPlatform {} {
global tcl_platform
if {[info exists tcl_platform(platform)]} then {
set platform $tcl_platform(platform)
if {[info exists tcl_platform(machine)]} then {
set machine $tcl_platform(machine)
} else {
set machine ""
}
switch -exact -- $platform {
windows {
switch -exact -- $machine {
intel -
ia32_on_win64 {
return win32-x86
}
arm {
return win32-arm
}
ia64 {
return win64-ia64
}
amd64 {
return win64-x64
}
arm64 {
return win64-arm64
}
}
}
}
}
return ""
}
#
# NOTE: This procedure verifies the platform specified by the caller. The
# platform argument must be an empty string -OR- one of the literal
# strings "neutral", "win32-arm", "win32-x86", "win64-arm64",
# "win64-ia64", or "win64-x64". An empty string means that the
# associated entity does not require a specific platform. The
# varName argument is the name of a variable in the context of the
# immediate caller that will receive a modified platform name, if
# applicable. Upon failure, a script error will be raised. The
# return value is undefined.
#
proc verifyPlatform { platform varName } {
#
# NOTE: The platform name must be matched exactly and case-sensitively.
#
switch -exact -- $platform {
"" {
#
# NOTE: The empty string means "attempt to automatically detect" the
# necessary platform based on context information that may be
# present in the context of the immediate caller. If this is
# not possible, a script error will be raised.
#
upvar 1 language language
if {![info exists language]} then {
error "unable to detect language"
}
upvar 1 version version
if {![info exists version]} then {
error "unable to detect version"
}
upvar 1 packageName packageName
if {[info exists packageName]} then {
set localPackageName $packageName
} else {
set localPackageName ""
}
upvar 1 usePgp usePgp
if {[info exists usePgp]} then {
set localUsePgp $usePgp
} else {
set localUsePgp false
}
#
# NOTE: Download the list of platforms associated with this package
# from the package repository server. This may fail and raise
# a script error.
#
set platforms [downloadAllPlatforms \
$language $version $localPackageName $localUsePgp]
if {[string length $varName] > 0} then {
upvar 1 $varName newPlatform
}
#
# NOTE: Check the current platform and the neutral platform, in that
# order, to see if that platform is supported by the package
# being saught. If so, return that platform.
#
foreach thisPlatform [list [getPlatform] neutral] {
if {[lsearch -exact $platforms $thisPlatform] != -1} then {
set newPlatform $thisPlatform
return
}
}
#
# NOTE: If this point is reached, there are no supported platforms
# that are compatible with the current one for the specified
# package.
#
error "could not automatically detect platform"
}
neutral -
win32-arm -
win32-x86 -
win64-arm64 -
win64-ia64 -
win64-x64 {
|
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
|
} else {
file delete -force -- $temporaryDirectory
}
return [expr {$compare > 0}]
}
#
# NOTE: This procedure downloads a single file from the package file server,
# writing its contents to the specified local file name. It can also
# verify the OpenPGP signatures. When an OpenPGP signature file is
# downloaded, this procedure assumes the corresponding data file was
# already downloaded (i.e. since OpenPGP needs both to perform the
# signature checks). The language argument must be one of the
# literal strings "eagle", "tcl", or "client". The version argument
# must be one of the literal strings "8.4", "8.5", or "8.6" when the
# language is "tcl" -OR- the literal string "1.0" when the language
# is either "eagle" or "client". The platform argument must be an
# empty string -OR- one of the literal strings "neutral", "win32-arm",
# "win32-x86", "win64-arm64", "win64-ia64", or "win64-x64". An empty
# string means that the associated package does not require a specific
# platform. The fileName argument is a file name relative to the
# language and version-specific directory on the package file server.
# The localFileName argument is the file name where the downloaded
# file should be written. The usePgp argument should be non-zero when
# an OpenPGP signature file needs to be downloaded and verified for
# the downloaded file.
#
proc downloadOneFile {
language version platform fileName localFileName usePgp } {
variable baseUri
variable downloadUri
variable downloadUrn
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
|
} else {
file delete -force -- $temporaryDirectory
}
return [expr {$compare > 0}]
}
#
# NOTE: This procedure downloads a manitest from the package file server,
# writing its contents to the specified local file name. It can also
# verify the OpenPGP signature. The language argument must be one of
# the literal strings "eagle", "tcl", or "client". The version
# argument must be one of the literal strings "8.4", "8.5", or "8.6"
# when the language is "tcl" -OR- the literal string "1.0" when the
# language is either "eagle" or "client". The packageName argument
# is a directory name relative to the language and version-specific
# directory on the package file server and may be an empty string.
# The localFileName argument is the file name where the downloaded
# file should be written. The usePgp argument should be non-zero
# when an OpenPGP signature needs to be verified for the downloaded
# file.
#
proc downloadAllPlatforms { language version packageName usePgp } {
variable baseUri
variable platformsUri
variable platformsUrn
variable temporaryRootDirectory
set temporaryDirectory [file join \
$temporaryRootDirectory [appendArgs \
pkgd_plat_ [::PackageRepository::getUniqueSuffix]]]
set localFileName [file join $temporaryDirectory manifest.txt]
file mkdir [file dirname $localFileName]
#
# NOTE: First, build the final URI to download from the remote package
# repository.
#
set uri [subst $platformsUri]
#
# NOTE: Then, in one step, download the file from the package file
# server and write it to the specified local file.
#
writeFile $localFileName [getPackageFile $uri]
#
# NOTE: Is use of OpenPGP for signature verification enabled? Also,
# did we just download an OpenPGP signature file?
#
if {$usePgp && [isOpenPgpSignatureFileName $localFileName true]} then {
#
# NOTE: Attempt to verify the OpenPGP signature. If this fails,
# an error is raised.
#
if {![::PackageRepository::verifyOpenPgpSignature $localFileName]} then {
error [appendArgs \
"bad OpenPGP signature \"" $localFileName \"]
}
}
#
# NOTE: Initialize list of platforms to return. This will be populated
# based on the platform directories available in the downloaded
# manfiest data.
#
set platforms [list]
#
# NOTE: Read the (OpenPGP verified) Fossil manifest data from the local
# file and split it into lines.
#
set data [readFile $localFileName]; set lines [split $data \n]
foreach line $lines {
if {[string range $line 0 1] eq "F "} then {
set fileName [lindex [split $line " "] 1]
if {[string match [file join \
$language $version * $packageName *] $fileName]} then {
set directory [lindex [file split $fileName] 2]
if {[string length $directory] > 0} then {
lappend platforms $directory
}
}
}
}
return [lsort -unique $platforms]
}
#
# NOTE: This procedure downloads a single file from the package file server,
# writing its contents to the specified local file name. It can also
# verify the OpenPGP signatures. When an OpenPGP signature file is
# downloaded, this procedure assumes the corresponding data file was
# already downloaded (i.e. since OpenPGP needs both to perform the
# signature checks). The language argument must be one of the
# literal strings "eagle", "tcl", or "client". The version argument
# must be one of the literal strings "8.4", "8.5", or "8.6" when the
# language is "tcl" -OR- the literal string "1.0" when the language
# is either "eagle" or "client". The platform argument must be an
# empty string -OR- one of the literal strings "neutral", "win32-arm",
# "win32-x86", "win64-arm64", "win64-ia64", or "win64-x64". An empty
# string means that the associated package does not require a specific
# platform. The fileName argument is a file name relative to the
# language and version-specific directory on the package file server.
# The localFileName argument is the file name where the downloaded
# file should be written. The usePgp argument should be non-zero when
# the OpenPGP signature file needs to be verified for the downloaded
# file.
#
proc downloadOneFile {
language version platform fileName localFileName usePgp } {
variable baseUri
variable downloadUri
variable downloadUrn
|