Check-in [0f6fc67b10]
Not logged in
Overview
Comment:All package scripts must now use Unix-style line-endings. Make the downloader use a unique temporary directory name per run. Normalize file names used by the downloader. Enhance the downloader so it verifies PGP signatures if requested, adds to the auto-path only if requested, and returns the final list of directories.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0f6fc67b10ad890ef6544d1d477f0e5051fdce60
User & Date: mistachkin on 2016-08-19 01:42:40
Other Links: manifest | tags
Context
2016-08-19
02:27
In the package downloader client, replace all uses of 'pkgr' with 'pkgd'. check-in: 786ddec706 user: mistachkin tags: trunk
01:42
All package scripts must now use Unix-style line-endings. Make the downloader use a unique temporary directory name per run. Normalize file names used by the downloader. Enhance the downloader so it verifies PGP signatures if requested, adds to the auto-path only if requested, and returns the final list of directories. check-in: 0f6fc67b10 user: mistachkin tags: trunk
01:20
For the AES Tcl package, use PGP signatures. check-in: 96c1cb0da8 user: mistachkin tags: trunk
Changes

Modified client/pkgd.eagle from [c4607ff2e7] to [0c6ca1e162].

82
83
84
85
86
87
88

89
90
91
92
93
94
95
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96







+







  # NOTE: This procedure adds a directory to the auto-path of the specified
  #       language (i.e. native Tcl or Eagle).  The directory will not be
  #       added if it is already present.  The language argument must be the
  #       literal string "eagle" or the literal string "tcl".  The directory
  #       argument is the fully qualified path for the directory to add to
  #       the auto-path.
  #
  # <public>
  proc addToAutoPath { language directory } {
    #
    # NOTE: Add the specified directory to the auto-path if not already
    #       present.
    #
    if {[string length $language] == 0 || $language eq "eagle"} then {
      if {[isEagle]} then {
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
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







-
+
+
+
+
+
+

+
-
+
+


















-
+

+
+
+



-
+

-
+

-
+



+
+
+


















-
-
+
+

-
-
+
+







+


+


-
+
+

-
-
+
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+




+
-
-
-
+
+
+
+
+
+







  #       literal string "tcl".  The version argument must be the literal
  #       string "8.4", "8.5", or "8.6" when the language is "tcl" -OR-
  #       the literal string "1.0" when the language is "eagle".  The
  #       fileNames argument must be a well-formed list of file names to
  #       download, each one relative to the language/version-specific
  #       directory on the package file server.  The persistent argument
  #       should be non-zero if the downloaded files should be saved to
  #       permanent storage for subsequent use.
  #       permanent storage for subsequent use.  The usePgp argument
  #       should be non-zero when an OpenPGP signature file needs to be
  #       downloaded and verified for each downloaded file.  The
  #       useAutoPath argument should be non-zero to modify the auto-path
  #       to include the temporary or persistent directories containing
  #       the downloaded files.
  #
  # <public>
  proc downloadFiles { language version fileNames persistent } {
  proc downloadFiles {
          language version fileNames persistent usePgp useAutoPath } {
    variable baseUri
    variable downloadUri
    variable persistentDirectory
    variable quiet

    if {[string length $language] == 0 || $language eq "eagle"} then {
      if {$version ne "1.0"} then {
        error "unsupported Eagle version"
      }
    } elseif {$language eq "tcl"} then {
      if {$version ne "8.4" && $version ne "8.5" && $version ne "8.6"} then {
        error "unsupported Tcl version"
      }
    } else {
      error "unsupported language"
    }

    if {$persistent} then {
      set downloadRootDirectory [file join $persistentDirectory]
      set downloadRootDirectory $persistentDirectory
    } else {
      set directoryNameOnly [appendArgs \
          pkgd_ [string trim [pid] -] _ [string trim [clock seconds] -]]

      global env

      if {[info exists env(PKGD_TEMP)]} then {
        set downloadRootDirectory [file join $env(PKGD_TEMP) pkgr]
        set downloadRootDirectory $env(PKGD_TEMP)
      } elseif {[info exists env(TEMP)]} then {
        set downloadRootDirectory [file join $env(TEMP) pkgr]
        set downloadRootDirectory $env(TEMP)
      } elseif {[info exists env(TMP)]} then {
        set downloadRootDirectory [file join $env(TMP) pkgr]
        set downloadRootDirectory $env(TMP)
      } else {
        error "please set PKGD_TEMP (via environment) to temporary directory"
      }

      set downloadRootDirectory [file join \
          $downloadRootDirectory $directoryNameOnly]
    }

    set downloadDirectories [list]

    foreach fileName $fileNames {
      if {[string length $fileName] == 0 || \
          [file pathtype $fileName] ne "relative"} then {
        error [appendArgs \
            "bad file name \"" $fileName "\", not relative"]
      }

      set directoryParts [file split [file dirname $fileName]]

      if {[llength $directoryParts] == 0} then {
        error [appendArgs \
            "bad file name \"" $fileName "\", no directory parts"]
      }

      set downloadDirectory [eval file join \
          [list $downloadRootDirectory] $directoryParts]
      set downloadDirectory [file normalize [eval file join \
          [list $downloadRootDirectory] $directoryParts]]

      set downloadFileName [file join $downloadDirectory \
          [file tail $fileName]]
      set downloadFileName [file normalize [file join \
          $downloadDirectory [file tail $fileName]]]

      if {!$persistent} then {
        catch {file delete $downloadFileName}
      }

      file mkdir [file dirname $downloadFileName]

      set savedFileName $fileName
      set fileName [file join $language $version $fileName]
      set uri [subst $downloadUri]
      set fileName $savedFileName

      if {[isEagle]} then {
        writeFile $downloadFileName [interp readorgetscriptfile -- "" $uri]
        writeFile $downloadFileName \
            [interp readorgetscriptfile -- "" $uri]
      } else {
        writeFile $downloadFileName [::PackageRepository::getFileViaHttp \
            $uri 10 stdout $quiet]
        writeFile $downloadFileName \
            [::PackageRepository::getFileViaHttp $uri 10 stdout $quiet]
      }

      if {$usePgp} then {
        set downloadSignatureFileName [appendArgs $downloadFileName .asc]

        set savedFileName $fileName
        set fileName [file join \
            $language $version [appendArgs $fileName .asc]]

        set uri [subst $downloadUri]
        set fileName $savedFileName

        if {[isEagle]} then {
          writeFile $downloadSignatureFileName \
              [interp readorgetscriptfile -- "" $uri]
        } else {
          writeFile $downloadSignatureFileName \
              [::PackageRepository::getFileViaHttp $uri 10 stdout $quiet]
        }

        if {![::PackageRepository::verifyPgpSignature \
            $downloadSignatureFileName]} then {
          error [appendArgs \
              "bad PGP signature \"" $downloadSignatureFileName \"]
        }
      }

      lappend downloadDirectories [file dirname $downloadDirectory]
      lappend downloadDirectories $downloadDirectory
    }

    set downloadDirectories [lsort -unique $downloadDirectories]

    if {$useAutoPath} then {
    foreach downloadDirectory $downloadDirectories {
      addToAutoPath $language $downloadDirectory
    }
      foreach downloadDirectory $downloadDirectories {
        addToAutoPath $language $downloadDirectory
      }
    }

    return $downloadDirectories
  }

  #
  # NOTE: Setup the variables, within this namespace, used by this script.
  #
  setupDownloadVars

Modified client/pkgd.eagle.harpy from [82723fcc45] to [3ca43ce2f2].

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
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







-
+


-
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


    THE ASSOCIATED SOFTWARE MAY NOT WORK PROPERLY IF THIS FILE IS ALTERED.
-->
<Certificate xmlns="https://eagle.to/2011/harpy"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Protocol>None</Protocol>
  <Vendor>Mistachkin Systems</Vendor>
  <Id>2c09ab50-08d8-47a0-8d50-96529e4cf6fd</Id>
  <Id>df73bc96-0ad4-43ed-9653-7f8f36169967</Id>
  <HashAlgorithm>SHA512</HashAlgorithm>
  <EntityType>Script</EntityType>
  <TimeStamp>2016-08-17T22:38:23.1247578Z</TimeStamp>
  <TimeStamp>2016-08-19T01:42:14.2969219Z</TimeStamp>
  <Duration>-1.00:00:00</Duration>
  <Key>0x2c322765603b5278</Key>
  <Signature>
    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
  </Signature>
</Certificate>

Modified client/pkgr.eagle from [637e610e45] to [9dc3f0e9e9].

336
337
338
339
340
341
342
343


344
345
346
347
348
349
350
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351







-
+
+







  # NOTE: This procedure issues an HTTP request that should return metadata
  #       that can be used to load and/or provide the specified package.
  #       The apiKey argument is the API key to use -OR- an empty string if
  #       a public package is being looked up.  The package argument is the
  #       name of the package, it cannot be an empty string.  The version
  #       argument is the specific version being looked up -OR- an empty
  #       string for any available version.  This procedure may raise script
  #       errors.
  #       errors.  All line-endings are normalized to Unix-style; therefore,
  #       all script signatures must assume this.
  #
  proc getLookupData { apiKey package version } {
    variable verboseUriDownload

    set uri [getLookupUri $apiKey $package $version]

    if {[string length $uri] == 0} then {
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
367
368
369
370
371
372
373

374
375
376
377
378
379
380







-







    if {$verboseUriDownload} then {
      pkgLog [appendArgs \
          "raw response data is: " $data]
    }

    set data [string map [list &lt\; < &gt\; > &quot\; \" &amp\; &] $data]
    set data [string map [list \r\n \n \r \n] $data]
    set data [string map [list \n \r\n] $data]
    set data [string trim $data]

    return $data
  }

  #
  # NOTE: This procedure attempts to extract the lookup code from the raw

Modified client/pkgr.eagle.harpy from [098ea262fd] to [3faa5a2158].

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
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







-
+


-
+



-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


    THE ASSOCIATED SOFTWARE MAY NOT WORK PROPERLY IF THIS FILE IS ALTERED.
-->
<Certificate xmlns="https://eagle.to/2011/harpy"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Protocol>None</Protocol>
  <Vendor>Mistachkin Systems</Vendor>
  <Id>ba94806a-9b8d-4e88-bab7-13bf861cac0d</Id>
  <Id>4e5a63d2-af93-4521-9477-bd723121aa3a</Id>
  <HashAlgorithm>SHA512</HashAlgorithm>
  <EntityType>Script</EntityType>
  <TimeStamp>2016-08-19T00:09:46.0088359Z</TimeStamp>
  <TimeStamp>2016-08-19T01:36:23.6406719Z</TimeStamp>
  <Duration>-1.00:00:00</Duration>
  <Key>0x2c322765603b5278</Key>
  <Signature>
    QwuM/tDLPKZLpAVJgsRw0+sjnxIouFcqm1IDjMqfdIv35x4sKBaXvMRTzid60II+xLcH7HlPB5yA
    TdoxpEOpQDcxb1td6QA6x83QR/sNrHjENQhdBLRlMB85zb4BDYoeBxRZffaVJ9/DcUGMBFjaCnq9
    fvMwy8Zrfn9gchj62qIQi325ZmoAEjx9gNxqZ04VgKS9gVv/zrtCTjI0a005UnoCLvJ9pYwbI8JT
    +froJJNq33wGV6AhZgtDz68oztHEoeo4VPnKK+eWNN6Prc3zmV4DBZp48PiQRqGjJlvjcnptazRl
    A5dSgbCXhqQ3ZiZg1oCytoo44zskijZMXweS9XMXe4RFR2/norxDMpRVkGNjsg1Aa9Vp2MiyZt55
    05VWuH6REndSOlN81GvIJGnRm/YKM2fplp98/EVrhQqMAR60RZvqsCgn+JTwgEL5SS40v+iK+1mM
    fKTuJkox07Vn4swSFcDyXhZroloIYSQmK/Il1+MCyQbQXntzdGLN6onuK/3ZITZneAMFHnwYX/bz
    Usyuixc3tP8dSVKz42ejdxRfMu9S3FakXLUOt9mWUvVIsS68wjyII4+GycvpbD4M3aHa7L8AiawD
    qZNeRZ8Teksxhy1UGB10LvkVmmdNew+N6v1MPwVPCT607hJNmmztjp7UMch1mN/l79yzw1LvyM+F
    eGe0vkfx+Z0FztiPh7F140zQumhktQl5ifl5yrt0hdNS9fGPI5PLyxbQuvstPo7PG9JNfLGRcnje
    etkTVnmXN2g3jYIufHMT03pQZE3F4/FELoVPdddXbf/CnoN6ZRCvX1FiznA+7AHJB1Xhw4LhOqiq
    erhj9JCAHjyqj+mgdybLeE+5Qzc3CXvWldTiFsthwl60JmiJ8zqElVOIyvIfhGveWN3WTfamQl4A
    iHDIirJy/LYROkbMYFCpJy28xDl/E9l5r+mdW9mSsJMfToUT4Lg9qtVa90H8qzeGKp/DIOHM1MEG
    cFDarH3qb8V1+hsbxMlku23kiJ/LYYIIthLY9WvAkJQXp7yM7Dm5yAkUvIrsjrKNdvQF0ZVmsvY9
    4dt/xKbnOLGMwZldgHL18JU6tnqiLFHT8SXjJZVgM5swrfTxhOaZny/f4TebxiFbg6puIvkmFHXE
    jOQz3so7pMb2LCzIme8WLDUsCdWX3KKSwtL1c0PGSjwEAtB6fPyqeJhTFXoUqAu6p64eqiu4uc4d
    voY8o0BLHwsb1KduLHK/a96qRdCZrOFy8ppftMg1D4FP65696Fd9xulY6XWTaOCIRibWwdtUP/As
    j3a9uwEU6kxYZw8IPQZmqGlrd1bDclzIEWTxD8tRgzVLWhErt6wRGf6V8whyHBllWBRzPgTciA==
    l5ZPkxTFQLfOcDb2621qaSQGrIVw0S/wyplhWpPEtUmGN68Ik3frACol542j1s6ZfJJ86hAyItuK
    KcQ5S3FiuX41IqMj3ZbeefGdeGNwxiE2oOpXy45NmkOmlk+z2XXxiLivX6TCEsPUcLWvOfLzDAxV
    HKew9JiDbf5fEQ1GLZX2/8QnV/yO2gaKiSAieUTFRyiptZBFKRNeW/2A+TsjN6L9UIxG3hDh1DL9
    oQ27IZdLqyzTdM8XMiSKec+4ODa+irEbv7T4M4f36V0RQ3oOsGFYS9BVekbzoFAM2VCefSV9an/O
    2difN18JZui+X7xN3j11Oa2tgLOIj7oJwlhNfE/d4kbiHpMQ+h1lIl1CwuwOoz8SxVdps+GrE8vn
    wo4fCkC1I0vLiCj8D8/4/Tro7X8YQgR2QhonSH7JNjynf0ue/p3PDHYJO2cM68evaOG1FdYgKPra
    +rodzUuEPCP7J0IPu009uP2OBPeOzJTVcFcYmj5/lBNY2WTN5/jdeNYhEBCJVzdcX+xvzgZndcf5
    6qUCzeW01EK0EvcEwOe0dxxOL6rgxKgx0Dg7YJDEm8k1lLcaqprkzBiy6ePYrAfGBaqwGmtGseTs
    PWrziCd/ECzAM1UsJM4l3BfClx++GMEeeQC9XE6DyYfQ9tKc2LL5/9qaZLiyvg7r1OxU8RjDBEEA
    tDDPNdYL4RdP7+iA8DJQ33+yVlP5/dNJXoW+L6mpZoaLAeetdT4N19gLRTqbIolOY75+O8wWByR/
    9P3kwBOMNS/2Y8Rv56Nkv91xhpKX2dmD8Nc9ctLLb5kI/GQeFSwOAucOV8vPnfRl5c5X13IMwZpC
    arK2FUguZlS+vKWxsGiff7OBB3GCjKagMYA9E/9+4iO391Pc2h1Q2ZdVgWW1Oo0RHFmrIkOu7Cwg
    AxwPiO7JcPSZFsbt0ahfBd43/m/SG0fTskYb+tUlLDqRQe/boj5YwiLQeFoc6Cj+lrh4sMvl42xc
    rAoKBbuLbWBam2hExpxFtVNpERFcSiFSU27LHPVmj+5MvmSGEGmznuGbMmmqi1g4xeADQDChFvMU
    pc6OUpHIkT0EMIPXFj1RWNhjkwv1dK/pO6Ewgf7PltpHdkP1ohPA2yTxkB0a7NRzX69SeY6EPxyM
    LXUcLH+PR7UywOnU0UJfHIJQDbvjGhfDAN7pXc1nESuDvae/D/Phearf9M2gd9rGl/GIKoZYh+iu
    FQxAydBWAQOdQ03Hwy3igLHaShP/ApNzHNyPF1m1FHsFSb+kNeEhmf0xZwWWxq7qAo6cwvY+fiNF
    NrRL6GlDah8g/+tj/YZH3VZ45Hnsa3JB+uqbGdfh+iC462NI2G6BFwbbRDeQxKD1tJq9wXcgqw==
  </Signature>
</Certificate>