Hex Artifact Content

Artifact dae13120c11a9ad59af48885536cb920fbb4bda3:


0000: 23 21 20 2f 75 73 72 2f 62 69 6e 2f 65 6e 76 20  #! /usr/bin/env 
0010: 62 61 73 68 0a 0a 23 0a 23 20 43 6f 70 79 72 69  bash..#.# Copyri
0020: 67 68 74 20 28 63 29 20 32 30 31 34 20 20 52 6f  ght (c) 2014  Ro
0030: 79 20 4b 65 65 6e 65 0a 23 0a 23 20 50 65 72 6d  y Keene.#.# Perm
0040: 69 73 73 69 6f 6e 20 69 73 20 68 65 72 65 62 79  ission is hereby
0050: 20 67 72 61 6e 74 65 64 2c 20 66 72 65 65 20 6f   granted, free o
0060: 66 20 63 68 61 72 67 65 2c 20 74 6f 20 61 6e 79  f charge, to any
0070: 20 70 65 72 73 6f 6e 20 6f 62 74 61 69 6e 69 6e   person obtainin
0080: 67 20 61 20 63 6f 70 79 0a 23 20 6f 66 20 74 68  g a copy.# of th
0090: 69 73 20 73 6f 66 74 77 61 72 65 20 61 6e 64 20  is software and 
00a0: 61 73 73 6f 63 69 61 74 65 64 20 64 6f 63 75 6d  associated docum
00b0: 65 6e 74 61 74 69 6f 6e 20 66 69 6c 65 73 20 28  entation files (
00c0: 74 68 65 20 22 53 6f 66 74 77 61 72 65 22 29 2c  the "Software"),
00d0: 20 74 6f 20 64 65 61 6c 0a 23 20 69 6e 20 74 68   to deal.# in th
00e0: 65 20 53 6f 66 74 77 61 72 65 20 77 69 74 68 6f  e Software witho
00f0: 75 74 20 72 65 73 74 72 69 63 74 69 6f 6e 2c 20  ut restriction, 
0100: 69 6e 63 6c 75 64 69 6e 67 20 77 69 74 68 6f 75  including withou
0110: 74 20 6c 69 6d 69 74 61 74 69 6f 6e 20 74 68 65  t limitation the
0120: 20 72 69 67 68 74 73 0a 23 20 74 6f 20 75 73 65   rights.# to use
0130: 2c 20 63 6f 70 79 2c 20 6d 6f 64 69 66 79 2c 20  , copy, modify, 
0140: 6d 65 72 67 65 2c 20 70 75 62 6c 69 73 68 2c 20  merge, publish, 
0150: 64 69 73 74 72 69 62 75 74 65 2c 20 73 75 62 6c  distribute, subl
0160: 69 63 65 6e 73 65 2c 20 61 6e 64 2f 6f 72 20 73  icense, and/or s
0170: 65 6c 6c 0a 23 20 63 6f 70 69 65 73 20 6f 66 20  ell.# copies of 
0180: 74 68 65 20 53 6f 66 74 77 61 72 65 2c 20 61 6e  the Software, an
0190: 64 20 74 6f 20 70 65 72 6d 69 74 20 70 65 72 73  d to permit pers
01a0: 6f 6e 73 20 74 6f 20 77 68 6f 6d 20 74 68 65 20  ons to whom the 
01b0: 53 6f 66 74 77 61 72 65 20 69 73 0a 23 20 66 75  Software is.# fu
01c0: 72 6e 69 73 68 65 64 20 74 6f 20 64 6f 20 73 6f  rnished to do so
01d0: 2c 20 73 75 62 6a 65 63 74 20 74 6f 20 74 68 65  , subject to the
01e0: 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f 6e 64 69   following condi
01f0: 74 69 6f 6e 73 3a 0a 23 0a 23 20 54 68 65 20 61  tions:.#.# The a
0200: 62 6f 76 65 20 63 6f 70 79 72 69 67 68 74 20 6e  bove copyright n
0210: 6f 74 69 63 65 20 61 6e 64 20 74 68 69 73 20 70  otice and this p
0220: 65 72 6d 69 73 73 69 6f 6e 20 6e 6f 74 69 63 65  ermission notice
0230: 20 73 68 61 6c 6c 20 62 65 20 69 6e 63 6c 75 64   shall be includ
0240: 65 64 20 69 6e 0a 23 20 61 6c 6c 20 63 6f 70 69  ed in.# all copi
0250: 65 73 20 6f 72 20 73 75 62 73 74 61 6e 74 69 61  es or substantia
0260: 6c 20 70 6f 72 74 69 6f 6e 73 20 6f 66 20 74 68  l portions of th
0270: 65 20 53 6f 66 74 77 61 72 65 2e 0a 23 0a 23 20  e Software..#.# 
0280: 54 48 45 20 53 4f 46 54 57 41 52 45 20 49 53 20  THE SOFTWARE IS 
0290: 50 52 4f 56 49 44 45 44 20 22 41 53 20 49 53 22  PROVIDED "AS IS"
02a0: 2c 20 57 49 54 48 4f 55 54 20 57 41 52 52 41 4e  , WITHOUT WARRAN
02b0: 54 59 20 4f 46 20 41 4e 59 20 4b 49 4e 44 2c 20  TY OF ANY KIND, 
02c0: 45 58 50 52 45 53 53 20 4f 52 0a 23 20 49 4d 50  EXPRESS OR.# IMP
02d0: 4c 49 45 44 2c 20 49 4e 43 4c 55 44 49 4e 47 20  LIED, INCLUDING 
02e0: 42 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20  BUT NOT LIMITED 
02f0: 54 4f 20 54 48 45 20 57 41 52 52 41 4e 54 49 45  TO THE WARRANTIE
0300: 53 20 4f 46 20 4d 45 52 43 48 41 4e 54 41 42 49  S OF MERCHANTABI
0310: 4c 49 54 59 2c 0a 23 20 46 49 54 4e 45 53 53 20  LITY,.# FITNESS 
0320: 46 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41 52  FOR A PARTICULAR
0330: 20 50 55 52 50 4f 53 45 20 41 4e 44 20 4e 4f 4e   PURPOSE AND NON
0340: 49 4e 46 52 49 4e 47 45 4d 45 4e 54 2e 20 49 4e  INFRINGEMENT. IN
0350: 20 4e 4f 20 45 56 45 4e 54 20 53 48 41 4c 4c 20   NO EVENT SHALL 
0360: 54 48 45 0a 23 20 41 55 54 48 4f 52 53 20 4f 52  THE.# AUTHORS OR
0370: 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c 44 45   COPYRIGHT HOLDE
0380: 52 53 20 42 45 20 4c 49 41 42 4c 45 20 46 4f 52  RS BE LIABLE FOR
0390: 20 41 4e 59 20 43 4c 41 49 4d 2c 20 44 41 4d 41   ANY CLAIM, DAMA
03a0: 47 45 53 20 4f 52 20 4f 54 48 45 52 0a 23 20 4c  GES OR OTHER.# L
03b0: 49 41 42 49 4c 49 54 59 2c 20 57 48 45 54 48 45  IABILITY, WHETHE
03c0: 52 20 49 4e 20 41 4e 20 41 43 54 49 4f 4e 20 4f  R IN AN ACTION O
03d0: 46 20 43 4f 4e 54 52 41 43 54 2c 20 54 4f 52 54  F CONTRACT, TORT
03e0: 20 4f 52 20 4f 54 48 45 52 57 49 53 45 2c 20 41   OR OTHERWISE, A
03f0: 52 49 53 49 4e 47 20 46 52 4f 4d 2c 0a 23 20 4f  RISING FROM,.# O
0400: 55 54 20 4f 46 20 4f 52 20 49 4e 20 43 4f 4e 4e  UT OF OR IN CONN
0410: 45 43 54 49 4f 4e 20 57 49 54 48 20 54 48 45 20  ECTION WITH THE 
0420: 53 4f 46 54 57 41 52 45 20 4f 52 20 54 48 45 20  SOFTWARE OR THE 
0430: 55 53 45 20 4f 52 20 4f 54 48 45 52 20 44 45 41  USE OR OTHER DEA
0440: 4c 49 4e 47 53 20 49 4e 0a 23 20 54 48 45 20 53  LINGS IN.# THE S
0450: 4f 46 54 57 41 52 45 2e 0a 23 0a 0a 50 41 54 48  OFTWARE..#..PATH
0460: 3d 22 24 7b 50 41 54 48 7d 3a 24 28 63 64 20 22  ="${PATH}:$(cd "
0470: 24 28 64 69 72 6e 61 6d 65 20 22 24 7b 42 41 53  $(dirname "${BAS
0480: 48 5f 53 4f 55 52 43 45 5b 30 5d 7d 22 29 22 20  H_SOURCE[0]}")" 
0490: 26 26 20 70 77 64 29 22 0a 0a 61 70 70 66 73 64  && pwd)"..appfsd
04a0: 5f 6f 70 74 69 6f 6e 73 3d 28 29 0a 69 66 20 5b  _options=().if [
04b0: 20 22 24 31 22 20 3d 3d 20 22 2d 2d 63 61 63 68   "$1" == "--cach
04c0: 65 64 69 72 22 20 5d 3b 20 74 68 65 6e 0a 09 61  edir" ]; then..a
04d0: 70 70 66 73 64 5f 6f 70 74 69 6f 6e 73 3d 28 22  ppfsd_options=("
04e0: 24 7b 61 70 70 66 73 64 5f 6f 70 74 69 6f 6e 73  ${appfsd_options
04f0: 5b 40 5d 7d 22 20 27 2d 2d 63 61 63 68 65 64 69  [@]}" '--cachedi
0500: 72 27 20 22 24 32 22 29 0a 0a 09 73 68 69 66 74  r' "$2")...shift
0510: 3b 20 73 68 69 66 74 3b 0a 66 69 0a 0a 66 75 6e  ; shift;.fi..fun
0520: 63 74 69 6f 6e 20 63 61 6c 6c 5f 61 70 70 66 73  ction call_appfs
0530: 64 28 29 20 7b 0a 09 61 70 70 66 73 64 20 22 24  d() {..appfsd "$
0540: 7b 61 70 70 66 73 64 5f 6f 70 74 69 6f 6e 73 5b  {appfsd_options[
0550: 40 5d 7d 22 20 22 24 40 22 0a 7d 0a 0a 66 75 6e  @]}" "$@".}..fun
0560: 63 74 69 6f 6e 20 69 6e 76 61 6c 69 64 61 74 65  ction invalidate
0570: 28 29 20 7b 0a 09 63 61 6c 6c 5f 61 70 70 66 73  () {..call_appfs
0580: 64 20 2d 2d 73 71 6c 69 74 65 33 20 27 55 50 44  d --sqlite3 'UPD
0590: 41 54 45 20 73 69 74 65 73 20 53 45 54 20 74 74  ATE sites SET tt
05a0: 6c 20 3d 20 22 30 22 3b 27 0a 7d 0a 0a 66 75 6e  l = "0";'.}..fun
05b0: 63 74 69 6f 6e 20 72 65 6d 6f 76 65 5f 73 69 74  ction remove_sit
05c0: 65 28 29 20 7b 0a 09 6c 6f 63 61 6c 20 73 69 74  e() {..local sit
05d0: 65 0a 0a 09 73 69 74 65 3d 22 24 31 22 0a 0a 09  e...site="$1"...
05e0: 63 61 6c 6c 5f 61 70 70 66 73 64 20 2d 2d 73 71  call_appfsd --sq
05f0: 6c 69 74 65 33 20 27 44 45 4c 45 54 45 20 46 52  lite3 'DELETE FR
0600: 4f 4d 20 73 69 74 65 73 20 57 48 45 52 45 20 68  OM sites WHERE h
0610: 6f 73 74 6e 61 6d 65 20 3d 20 27 22 27 24 73 69  ostname = '"'$si
0620: 74 65 27 22 27 3b 20 44 45 4c 45 54 45 20 46 52  te'"'; DELETE FR
0630: 4f 4d 20 70 61 63 6b 61 67 65 73 20 57 48 45 52  OM packages WHER
0640: 45 20 68 6f 73 74 6e 61 6d 65 20 3d 20 27 22 27  E hostname = '"'
0650: 24 73 69 74 65 27 22 27 3b 27 20 7c 7c 20 72 65  $site'"';' || re
0660: 74 75 72 6e 20 31 0a 0a 09 63 6c 65 61 6e 0a 7d  turn 1...clean.}
0670: 0a 0a 66 75 6e 63 74 69 6f 6e 20 6d 69 72 72 6f  ..function mirro
0680: 72 28 29 20 7b 0a 09 6c 6f 63 61 6c 20 73 69 74  r() {..local sit
0690: 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 44 69 72  e destinationDir
06a0: 0a 09 6c 6f 63 61 6c 20 62 61 73 65 55 52 4c 20  ..local baseURL 
06b0: 69 6e 64 65 78 0a 09 6c 6f 63 61 6c 20 70 61 63  index..local pac
06c0: 6b 61 67 65 4c 69 73 74 0a 0a 09 6c 6f 63 61 6c  kageList...local
06d0: 20 6d 61 72 6b 65 72 0a 0a 09 73 69 74 65 3d 22   marker...site="
06e0: 24 31 22 0a 09 64 65 73 74 69 6e 61 74 69 6f 6e  $1"..destination
06f0: 44 69 72 3d 22 24 32 22 0a 0a 09 62 61 73 65 55  Dir="$2"...baseU
0700: 52 4c 3d 22 68 74 74 70 3a 2f 2f 24 7b 73 69 74  RL="http://${sit
0710: 65 7d 2f 61 70 70 66 73 22 0a 09 69 6e 64 65 78  e}/appfs"..index
0720: 3d 22 24 7b 62 61 73 65 55 52 4c 7d 2f 69 6e 64  ="${baseURL}/ind
0730: 65 78 22 0a 0a 09 69 66 20 5b 20 21 20 2d 65 20  ex"...if [ ! -e 
0740: 22 24 7b 64 65 73 74 69 6e 61 74 69 6f 6e 44 69  "${destinationDi
0750: 72 7d 22 20 5d 3b 20 74 68 65 6e 0a 09 09 6d 6b  r}" ]; then...mk
0760: 64 69 72 20 22 24 7b 64 65 73 74 69 6e 61 74 69  dir "${destinati
0770: 6f 6e 44 69 72 7d 22 20 7c 7c 20 72 65 74 75 72  onDir}" || retur
0780: 6e 20 31 0a 09 66 69 0a 0a 09 6d 61 72 6b 65 72  n 1..fi...marker
0790: 3d 22 24 28 6f 70 65 6e 73 73 6c 20 72 61 6e 64  ="$(openssl rand
07a0: 20 32 30 20 2d 68 65 78 29 22 0a 0a 09 28 0a 09   20 -hex)"...(..
07b0: 09 63 64 20 22 24 7b 64 65 73 74 69 6e 61 74 69  .cd "${destinati
07c0: 6f 6e 44 69 72 7d 22 20 7c 7c 20 65 78 69 74 20  onDir}" || exit 
07d0: 31 0a 0a 09 09 23 20 58 58 58 3a 54 4f 44 4f 3a  1....# XXX:TODO:
07e0: 20 54 68 69 73 20 64 6f 65 73 20 6e 6f 74 20 76   This does not v
07f0: 61 6c 69 64 61 74 65 20 74 68 65 20 73 69 67 6e  alidate the sign
0800: 61 74 75 72 65 0a 09 09 63 75 72 6c 20 2d 73 53  ature...curl -sS
0810: 4c 20 22 24 7b 69 6e 64 65 78 7d 22 20 3e 20 22  L "${index}" > "
0820: 69 6e 64 65 78 2e 24 7b 6d 61 72 6b 65 72 7d 22  index.${marker}"
0830: 0a 0a 09 09 70 61 63 6b 61 67 65 4c 69 73 74 48  ....packageListH
0840: 61 73 68 3d 22 24 28 63 61 74 20 22 69 6e 64 65  ash="$(cat "inde
0850: 78 2e 24 7b 6d 61 72 6b 65 72 7d 22 20 7c 20 63  x.${marker}" | c
0860: 75 74 20 2d 66 20 31 20 2d 64 20 2c 29 22 0a 09  ut -f 1 -d ,)"..
0870: 09 70 61 63 6b 61 67 65 4c 69 73 74 48 61 73 68  .packageListHash
0880: 4d 65 74 68 6f 64 3d 22 24 28 63 61 74 20 22 69  Method="$(cat "i
0890: 6e 64 65 78 2e 24 7b 6d 61 72 6b 65 72 7d 22 20  ndex.${marker}" 
08a0: 7c 20 63 75 74 20 2d 66 20 32 20 2d 64 20 2c 29  | cut -f 2 -d ,)
08b0: 22 0a 09 09 23 63 75 72 6c 20 2d 73 53 4c 20 22  "...#curl -sSL "
08c0: 24 7b 2e 2e 2e 7d 22 0a 0a 09 09 6d 76 20 22 69  ${...}"....mv "i
08d0: 6e 64 65 78 2e 24 7b 6d 61 72 6b 65 72 7d 22 20  ndex.${marker}" 
08e0: 69 6e 64 65 78 0a 09 29 20 7c 7c 20 72 65 74 75  index..) || retu
08f0: 72 6e 20 31 0a 0a 09 72 65 74 75 72 6e 20 30 0a  rn 1...return 0.
0900: 7d 0a 0a 66 75 6e 63 74 69 6f 6e 20 63 6c 65 61  }..function clea
0910: 6e 28 29 20 7b 0a 09 63 61 6c 6c 5f 61 70 70 66  n() {..call_appf
0920: 73 64 20 2d 2d 74 63 6c 20 22 24 28 63 61 74 20  sd --tcl "$(cat 
0930: 3c 3c 5c 5f 45 4f 46 5f 0a 09 09 75 6e 73 65 74  <<\_EOF_...unset
0940: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77   -nocomplain row
0950: 0a 09 09 3a 3a 61 70 70 66 73 3a 3a 64 62 20 65  ...::appfs::db e
0960: 76 61 6c 20 7b 53 45 4c 45 43 54 20 73 68 61 31  val {SELECT sha1
0970: 2c 20 68 6f 73 74 6e 61 6d 65 20 46 52 4f 4d 20  , hostname FROM 
0980: 70 61 63 6b 61 67 65 73 3b 7d 20 72 6f 77 20 7b  packages;} row {
0990: 0a 09 09 09 73 65 74 20 68 6f 73 74 6e 61 6d 65  ....set hostname
09a0: 20 5b 3a 3a 61 70 70 66 73 3a 3a 64 62 20 6f 6e   [::appfs::db on
09b0: 65 63 6f 6c 75 6d 6e 20 7b 53 45 4c 45 43 54 20  ecolumn {SELECT 
09c0: 68 6f 73 74 6e 61 6d 65 20 46 52 4f 4d 20 73 69  hostname FROM si
09d0: 74 65 73 20 57 48 45 52 45 20 68 6f 73 74 6e 61  tes WHERE hostna
09e0: 6d 65 20 3d 20 24 72 6f 77 28 68 6f 73 74 6e 61  me = $row(hostna
09f0: 6d 65 29 20 4c 49 4d 49 54 20 31 3b 7d 5d 0a 09  me) LIMIT 1;}]..
0a00: 09 09 69 66 20 7b 24 68 6f 73 74 6e 61 6d 65 20  ..if {$hostname 
0a10: 3d 3d 20 22 22 7d 20 7b 0a 09 09 09 09 63 6f 6e  == ""} {.....con
0a20: 74 69 6e 75 65 0a 09 09 09 7d 0a 0a 09 09 09 73  tinue....}.....s
0a30: 65 74 20 76 61 6c 69 64 5f 73 68 61 31 28 24 72  et valid_sha1($r
0a40: 6f 77 28 73 68 61 31 29 29 20 31 0a 09 09 09 3a  ow(sha1)) 1....:
0a50: 3a 61 70 70 66 73 3a 3a 64 62 20 65 76 61 6c 20  :appfs::db eval 
0a60: 7b 53 45 4c 45 43 54 20 66 69 6c 65 5f 73 68 61  {SELECT file_sha
0a70: 31 20 46 52 4f 4d 20 66 69 6c 65 73 20 57 48 45  1 FROM files WHE
0a80: 52 45 20 66 69 6c 65 5f 73 68 61 31 20 49 53 20  RE file_sha1 IS 
0a90: 4e 4f 54 20 4e 55 4c 4c 20 41 4e 44 20 66 69 6c  NOT NULL AND fil
0aa0: 65 5f 73 68 61 31 20 21 3d 20 27 27 20 41 4e 44  e_sha1 != '' AND
0ab0: 20 70 61 63 6b 61 67 65 5f 73 68 61 31 20 3d 20   package_sha1 = 
0ac0: 24 72 6f 77 28 73 68 61 31 29 3b 7d 20 73 75 62  $row(sha1);} sub
0ad0: 72 6f 77 20 7b 0a 09 09 09 09 73 65 74 20 76 61  row {.....set va
0ae0: 6c 69 64 5f 73 68 61 31 28 24 73 75 62 72 6f 77  lid_sha1($subrow
0af0: 28 66 69 6c 65 5f 73 68 61 31 29 29 20 31 0a 09  (file_sha1)) 1..
0b00: 09 09 7d 0a 09 09 7d 0a 0a 09 09 66 6f 72 65 61  ..}...}....forea
0b10: 63 68 20 66 69 6c 65 20 5b 67 6c 6f 62 20 2d 6e  ch file [glob -n
0b20: 6f 63 6f 6d 70 6c 61 69 6e 20 2d 74 61 69 6c 73  ocomplain -tails
0b30: 20 2d 64 69 72 65 63 74 6f 72 79 20 24 3a 3a 61   -directory $::a
0b40: 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72 20 7b  ppfs::cachedir {
0b50: 5b 30 2d 39 61 2d 66 5d 5b 30 2d 39 61 2d 66 5d  [0-9a-f][0-9a-f]
0b60: 2f 2a 2f 2a 2f 2a 2f 2a 7d 5d 20 7b 0a 09 09 09  /*/*/*/*}] {....
0b70: 73 65 74 20 73 68 61 31 20 5b 73 74 72 69 6e 67  set sha1 [string
0b80: 20 6d 61 70 20 5b 6c 69 73 74 20 22 2f 22 20 22   map [list "/" "
0b90: 22 20 22 5c 5c 22 20 22 22 5d 20 24 66 69 6c 65  " "\\" ""] $file
0ba0: 5d 0a 09 09 09 73 65 74 20 66 69 6c 65 20 5b 66  ]....set file [f
0bb0: 69 6c 65 20 6a 6f 69 6e 20 24 3a 3a 61 70 70 66  ile join $::appf
0bc0: 73 3a 3a 63 61 63 68 65 64 69 72 20 24 66 69 6c  s::cachedir $fil
0bd0: 65 5d 0a 0a 09 09 09 69 66 20 7b 5b 69 6e 66 6f  e].....if {[info
0be0: 20 65 78 69 73 74 73 20 76 61 6c 69 64 5f 73 68   exists valid_sh
0bf0: 61 31 28 24 73 68 61 31 29 5d 7d 20 7b 0a 09 09  a1($sha1)]} {...
0c00: 09 09 63 6f 6e 74 69 6e 75 65 0a 09 09 09 7d 0a  ..continue....}.
0c10: 0a 09 09 09 70 75 74 73 20 22 43 6c 65 61 6e 69  ....puts "Cleani
0c20: 6e 67 20 24 66 69 6c 65 22 0a 09 09 09 66 69 6c  ng $file"....fil
0c30: 65 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20  e delete -force 
0c40: 2d 2d 20 24 66 69 6c 65 0a 09 09 7d 0a 5f 45 4f  -- $file...}._EO
0c50: 46 5f 0a 09 29 22 0a 7d 0a 0a 66 75 6e 63 74 69  F_..)".}..functi
0c60: 6f 6e 20 63 6c 65 61 72 28 29 20 7b 0a 09 6c 6f  on clear() {..lo
0c70: 63 61 6c 20 70 61 63 6b 61 67 65 0a 0a 09 70 61  cal package...pa
0c80: 63 6b 61 67 65 3d 22 24 31 22 0a 0a 09 69 66 20  ckage="$1"...if 
0c90: 5b 20 2d 6e 20 22 24 7b 70 61 63 6b 61 67 65 7d  [ -n "${package}
0ca0: 22 20 5d 3b 20 74 68 65 6e 0a 09 09 65 63 68 6f  " ]; then...echo
0cb0: 20 22 6e 6f 74 20 69 6d 70 6c 65 6d 65 6e 74 65   "not implemente
0cc0: 64 22 20 3e 26 32 0a 0a 09 09 72 65 74 75 72 6e  d" >&2....return
0cd0: 20 31 0a 09 66 69 0a 0a 09 63 61 6c 6c 5f 61 70   1..fi...call_ap
0ce0: 70 66 73 64 20 2d 2d 74 63 6c 20 27 66 69 6c 65  pfsd --tcl 'file
0cf0: 20 64 65 6c 65 74 65 20 2d 66 6f 72 63 65 20 2d   delete -force -
0d00: 2d 20 7b 2a 7d 5b 67 6c 6f 62 20 2d 64 69 72 65  - {*}[glob -dire
0d10: 63 74 6f 72 79 20 24 3a 3a 61 70 70 66 73 3a 3a  ctory $::appfs::
0d20: 63 61 63 68 65 64 69 72 20 7b 5b 30 2d 39 61 2d  cachedir {[0-9a-
0d30: 66 5d 5b 30 2d 39 61 2d 66 5d 7d 5d 27 20 7c 7c  f][0-9a-f]}]' ||
0d40: 20 72 65 74 75 72 6e 20 31 0a 09 63 61 6c 6c 5f   return 1..call_
0d50: 61 70 70 66 73 64 20 2d 2d 73 71 6c 69 74 65 33  appfsd --sqlite3
0d60: 20 27 44 45 4c 45 54 45 20 46 52 4f 4d 20 73 69   'DELETE FROM si
0d70: 74 65 73 3b 20 44 45 4c 45 54 45 20 46 52 4f 4d  tes; DELETE FROM
0d80: 20 70 61 63 6b 61 67 65 73 3b 20 44 45 4c 45 54   packages; DELET
0d90: 45 20 46 52 4f 4d 20 66 69 6c 65 73 3b 20 56 41  E FROM files; VA
0da0: 43 55 55 4d 3b 27 20 7c 7c 20 72 65 74 75 72 6e  CUUM;' || return
0db0: 20 31 0a 7d 0a 0a 66 75 6e 63 74 69 6f 6e 20 69   1.}..function i
0dc0: 6e 73 74 61 6c 6c 28 29 20 7b 0a 09 6c 6f 63 61  nstall() {..loca
0dd0: 6c 20 73 69 74 65 20 70 61 63 6b 61 67 65 73 0a  l site packages.
0de0: 09 6c 6f 63 61 6c 20 70 61 63 6b 61 67 65 20 70  .local package p
0df0: 61 63 6b 61 67 65 64 69 72 0a 09 6c 6f 63 61 6c  ackagedir..local
0e00: 20 69 6e 63 6c 75 64 65 4c 69 62 0a 0a 09 69 6e   includeLib...in
0e10: 63 6c 75 64 65 4c 69 62 3d 27 30 27 0a 09 69 66  cludeLib='0'..if
0e20: 20 5b 20 22 24 31 22 20 3d 20 27 2d 6c 69 62 27   [ "$1" = '-lib'
0e30: 20 5d 3b 20 74 68 65 6e 0a 09 09 73 68 69 66 74   ]; then...shift
0e40: 0a 09 09 69 6e 63 6c 75 64 65 4c 69 62 3d 27 31  ...includeLib='1
0e50: 27 0a 09 66 69 0a 0a 09 73 69 74 65 3d 22 24 31  '..fi...site="$1
0e60: 22 0a 09 73 68 69 66 74 0a 0a 09 70 61 63 6b 61  "..shift...packa
0e70: 67 65 73 3d 28 22 24 40 22 29 0a 0a 09 69 66 20  ges=("$@")...if 
0e80: 5b 20 2d 7a 20 22 24 7b 73 69 74 65 7d 22 20 2d  [ -z "${site}" -
0e90: 6f 20 2d 7a 20 22 24 7b 70 61 63 6b 61 67 65 73  o -z "${packages
0ea0: 5b 2a 5d 7d 22 20 5d 3b 20 74 68 65 6e 0a 09 09  [*]}" ]; then...
0eb0: 65 63 68 6f 20 22 75 73 61 67 65 3a 20 61 70 70  echo "usage: app
0ec0: 66 73 2d 63 61 63 68 65 20 69 6e 73 74 61 6c 6c  fs-cache install
0ed0: 20 3c 73 69 74 65 3e 20 3c 70 61 63 6b 61 67 65   <site> <package
0ee0: 3e 2e 2e 2e 22 20 3e 26 32 0a 0a 09 09 72 65 74  >..." >&2....ret
0ef0: 75 72 6e 20 31 0a 09 66 69 0a 0a 09 66 6f 72 20  urn 1..fi...for 
0f00: 70 61 63 6b 61 67 65 20 69 6e 20 22 24 7b 70 61  package in "${pa
0f10: 63 6b 61 67 65 73 5b 40 5d 7d 22 3b 20 64 6f 0a  ckages[@]}"; do.
0f20: 09 09 70 61 63 6b 61 67 65 64 69 72 3d 22 2f 6f  ..packagedir="/o
0f30: 70 74 2f 61 70 70 66 73 2f 24 7b 73 69 74 65 7d  pt/appfs/${site}
0f40: 2f 24 7b 70 61 63 6b 61 67 65 7d 2f 70 6c 61 74  /${package}/plat
0f50: 66 6f 72 6d 2f 6c 61 74 65 73 74 22 0a 0a 09 09  form/latest"....
0f60: 23 23 20 58 58 58 3a 54 4f 44 4f 3a 20 41 6c 6c  ## XXX:TODO: All
0f70: 6f 77 20 69 6e 73 74 61 6c 6c 61 74 69 6f 6e 20  ow installation 
0f80: 74 6f 20 6f 74 68 65 72 20 6c 6f 63 61 74 69 6f  to other locatio
0f90: 6e 73 0a 09 09 6c 6e 20 2d 66 73 20 22 24 7b 70  ns...ln -fs "${p
0fa0: 61 63 6b 61 67 65 64 69 72 7d 22 2f 62 69 6e 2f  ackagedir}"/bin/
0fb0: 2a 20 2f 62 69 6e 2f 0a 09 09 69 66 20 5b 20 22  * /bin/...if [ "
0fc0: 24 7b 69 6e 63 6c 75 64 65 4c 69 62 7d 22 20 3d  ${includeLib}" =
0fd0: 20 27 31 27 20 5d 3b 20 74 68 65 6e 0a 09 09 09   '1' ]; then....
0fe0: 6c 6e 20 2d 66 73 20 22 24 7b 70 61 63 6b 61 67  ln -fs "${packag
0ff0: 65 64 69 72 7d 22 2f 6c 69 62 2f 2a 20 2f 6c 69  edir}"/lib/* /li
1000: 62 2f 0a 09 09 66 69 0a 09 64 6f 6e 65 0a 0a 09  b/...fi..done...
1010: 72 65 74 75 72 6e 20 30 0a 7d 0a 0a 6f 70 65 72  return 0.}..oper
1020: 61 74 69 6f 6e 3d 22 24 31 22 0a 73 68 69 66 74  ation="$1".shift
1030: 0a 63 61 73 65 20 22 24 6f 70 65 72 61 74 69 6f  .case "$operatio
1040: 6e 22 20 69 6e 0a 09 69 6e 73 74 61 6c 6c 29 0a  n" in..install).
1050: 09 09 69 6e 73 74 61 6c 6c 20 22 24 40 22 20 7c  ..install "$@" |
1060: 7c 20 65 78 69 74 20 31 0a 09 09 65 78 69 74 20  | exit 1...exit 
1070: 30 0a 09 09 3b 3b 0a 09 69 6e 76 61 6c 69 64 61  0...;;..invalida
1080: 74 65 29 0a 09 09 69 6e 76 61 6c 69 64 61 74 65  te)...invalidate
1090: 20 7c 7c 20 65 78 69 74 20 31 0a 09 09 3b 3b 0a   || exit 1...;;.
10a0: 09 72 65 6d 6f 76 65 2d 73 69 74 65 29 0a 09 09  .remove-site)...
10b0: 72 65 6d 6f 76 65 5f 73 69 74 65 20 22 24 40 22  remove_site "$@"
10c0: 20 7c 7c 20 65 78 69 74 20 31 0a 09 09 3b 3b 0a   || exit 1...;;.
10d0: 09 63 6c 65 61 6e 29 0a 09 09 63 6c 65 61 6e 20  .clean)...clean 
10e0: 7c 7c 20 65 78 69 74 20 31 0a 09 09 3b 3b 0a 09  || exit 1...;;..
10f0: 63 6c 65 61 72 29 0a 09 09 63 6c 65 61 72 20 22  clear)...clear "
1100: 24 40 22 20 7c 7c 20 65 78 69 74 20 31 0a 09 09  $@" || exit 1...
1110: 3b 3b 0a 09 68 6f 61 72 64 29 0a 09 09 65 63 68  ;;..hoard)...ech
1120: 6f 20 22 6e 6f 74 20 69 6d 70 6c 65 6d 65 6e 74  o "not implement
1130: 65 64 22 20 3e 26 32 0a 09 09 65 78 69 74 20 31  ed" >&2...exit 1
1140: 0a 0a 09 09 68 6f 61 72 64 20 22 24 40 22 20 7c  ....hoard "$@" |
1150: 7c 20 65 78 69 74 20 31 0a 09 09 65 78 69 74 20  | exit 1...exit 
1160: 30 0a 09 09 3b 3b 0a 09 6d 69 72 72 6f 72 29 0a  0...;;..mirror).
1170: 09 09 65 63 68 6f 20 22 6e 6f 74 20 69 6d 70 6c  ..echo "not impl
1180: 65 6d 65 6e 74 65 64 22 20 3e 26 32 0a 09 09 65  emented" >&2...e
1190: 78 69 74 20 31 0a 0a 09 09 6d 69 72 72 6f 72 20  xit 1....mirror 
11a0: 22 24 40 22 20 7c 7c 20 65 78 69 74 20 31 0a 09  "$@" || exit 1..
11b0: 09 65 78 69 74 20 30 0a 09 09 3b 3b 0a 09 2a 29  .exit 0...;;..*)
11c0: 0a 09 09 65 63 68 6f 20 22 55 73 61 67 65 3a 20  ...echo "Usage: 
11d0: 61 70 70 66 73 2d 63 61 63 68 65 20 7b 69 6e 76  appfs-cache {inv
11e0: 61 6c 69 64 61 74 65 7c 63 6c 65 61 6e 7c 63 6c  alidate|clean|cl
11f0: 65 61 72 7c 63 6c 65 61 72 20 3c 70 61 63 6b 61  ear|clear <packa
1200: 67 65 3e 7c 72 65 6d 6f 76 65 2d 73 69 74 65 20  ge>|remove-site 
1210: 3c 73 69 74 65 3e 7c 68 6f 61 72 64 20 3c 70 61  <site>|hoard <pa
1220: 63 6b 61 67 65 3e 7c 6d 69 72 72 6f 72 20 3c 73  ckage>|mirror <s
1230: 69 74 65 3e 20 3c 64 69 72 3e 7d 22 20 3e 26 32  ite> <dir>}" >&2
1240: 0a 0a 09 09 65 78 69 74 20 31 0a 09 09 3b 3b 0a  ....exit 1...;;.
1250: 65 73 61 63 0a 0a 70 6b 69 6c 6c 20 2d 48 55 50  esac..pkill -HUP
1260: 20 61 70 70 66 73 64 0a 0a 65 78 69 74 20 30 0a   appfsd..exit 0.