0000: 5c 20 6d 65 73 73 61 67 65 73 20 20 20 20 20 20 \ messages
0010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
0020: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
0030: 20 20 20 20 20 30 36 61 75 67 32 30 31 34 70 79 06aug2014py
0040: 0a 0a 5c 20 43 6f 70 79 72 69 67 68 74 20 28 43 ..\ Copyright (C
0050: 29 20 32 30 31 34 2d 32 30 31 36 20 20 20 42 65 ) 2014-2016 Be
0060: 72 6e 64 20 50 61 79 73 61 6e 0a 0a 5c 20 54 68 rnd Paysan..\ Th
0070: 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66 72 is program is fr
0080: 65 65 20 73 6f 66 74 77 61 72 65 3a 20 79 6f 75 ee software: you
0090: 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75 74 can redistribut
00a0: 65 20 69 74 20 61 6e 64 2f 6f 72 20 6d 6f 64 69 e it and/or modi
00b0: 66 79 0a 5c 20 69 74 20 75 6e 64 65 72 20 74 68 fy.\ it under th
00c0: 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65 20 47 e terms of the G
00d0: 4e 55 20 41 66 66 65 72 6f 20 47 65 6e 65 72 61 NU Affero Genera
00e0: 6c 20 50 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 l Public License
00f0: 20 61 73 20 70 75 62 6c 69 73 68 65 64 20 62 79 as published by
0100: 0a 5c 20 74 68 65 20 46 72 65 65 20 53 6f 66 74 .\ the Free Soft
0110: 77 61 72 65 20 46 6f 75 6e 64 61 74 69 6f 6e 2c ware Foundation,
0120: 20 65 69 74 68 65 72 20 76 65 72 73 69 6f 6e 20 either version
0130: 33 20 6f 66 20 74 68 65 20 4c 69 63 65 6e 73 65 3 of the License
0140: 2c 20 6f 72 0a 5c 20 28 61 74 20 79 6f 75 72 20 , or.\ (at your
0150: 6f 70 74 69 6f 6e 29 20 61 6e 79 20 6c 61 74 65 option) any late
0160: 72 20 76 65 72 73 69 6f 6e 2e 0a 0a 5c 20 54 68 r version...\ Th
0170: 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 is program is di
0180: 73 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 stributed in the
0190: 20 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 hope that it wi
01a0: 6c 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 5c 20 ll be useful,.\
01b0: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20 but WITHOUT ANY
01c0: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75 WARRANTY; withou
01d0: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 t even the impli
01e0: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 5c ed warranty of.\
01f0: 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54 59 MERCHANTABILITY
0200: 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52 20 or FITNESS FOR
0210: 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55 52 A PARTICULAR PUR
0220: 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 0a 5c POSE. See the.\
0230: 20 47 4e 55 20 41 66 66 65 72 6f 20 47 65 6e 65 GNU Affero Gene
0240: 72 61 6c 20 50 75 62 6c 69 63 20 4c 69 63 65 6e ral Public Licen
0250: 73 65 20 66 6f 72 20 6d 6f 72 65 20 64 65 74 61 se for more deta
0260: 69 6c 73 2e 0a 0a 5c 20 59 6f 75 20 73 68 6f 75 ils...\ You shou
0270: 6c 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 ld have received
0280: 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 a copy of the G
0290: 4e 55 20 41 66 66 65 72 6f 20 47 65 6e 65 72 61 NU Affero Genera
02a0: 6c 20 50 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 l Public License
02b0: 0a 5c 20 61 6c 6f 6e 67 20 77 69 74 68 20 74 68 .\ along with th
02c0: 69 73 20 70 72 6f 67 72 61 6d 2e 20 20 49 66 20 is program. If
02d0: 6e 6f 74 2c 20 73 65 65 20 3c 68 74 74 70 3a 2f not, see <http:/
02e0: 2f 77 77 77 2e 67 6e 75 2e 6f 72 67 2f 6c 69 63 /www.gnu.org/lic
02f0: 65 6e 73 65 73 2f 3e 2e 0a 0a 46 6f 72 77 61 72 enses/>...Forwar
0300: 64 20 61 76 61 6c 61 6e 63 68 65 2d 74 6f 20 28 d avalanche-to (
0310: 20 61 64 64 72 20 75 20 6f 3a 63 6f 6e 74 65 78 addr u o:contex
0320: 74 20 2d 2d 20 29 0a 46 6f 72 77 61 72 64 20 70 t -- ).Forward p
0330: 6b 2d 63 6f 6e 6e 65 63 74 20 28 20 6b 65 79 20 k-connect ( key
0340: 75 20 63 6d 64 6c 65 6e 20 64 61 74 61 6c 65 6e u cmdlen datalen
0350: 20 2d 2d 20 29 0a 46 6f 72 77 61 72 64 20 70 6b -- ).Forward pk
0360: 2d 63 6f 6e 6e 65 63 74 3f 20 28 20 6b 65 79 20 -connect? ( key
0370: 75 20 63 6d 64 6c 65 6e 20 64 61 74 61 6c 65 6e u cmdlen datalen
0380: 20 2d 2d 20 66 6c 61 67 20 29 0a 46 6f 72 77 61 -- flag ).Forwa
0390: 72 64 20 61 64 64 72 2d 63 6f 6e 6e 65 63 74 20 rd addr-connect
03a0: 28 20 6b 65 79 2b 61 64 64 72 20 75 20 63 6d 64 ( key+addr u cmd
03b0: 6c 65 6e 20 64 61 74 61 6c 65 6e 20 78 74 20 2d len datalen xt -
03c0: 2d 20 29 0a 46 6f 72 77 61 72 64 20 70 6b 2d 70 - ).Forward pk-p
03d0: 65 65 6b 3f 20 28 20 61 64 64 72 20 75 30 20 2d eek? ( addr u0 -
03e0: 2d 20 66 6c 61 67 20 29 0a 0a 3a 20 3f 68 61 73 - flag )..: ?has
03f0: 68 20 28 20 61 64 64 72 20 75 20 68 61 73 68 20 h ( addr u hash
0400: 2d 2d 20 29 20 3e 72 0a 20 20 20 20 32 64 75 70 -- ) >r. 2dup
0410: 20 72 40 20 23 40 20 64 30 3d 20 49 46 20 20 22 r@ #@ d0= IF "
0420: 22 20 32 73 77 61 70 20 72 3e 20 23 21 20 20 45 " 2swap r> #! E
0430: 4c 53 45 20 20 32 64 72 6f 70 20 72 64 72 6f 70 LSE 2drop rdrop
0440: 20 20 54 48 45 4e 20 3b 0a 0a 56 61 72 69 61 62 THEN ;..Variab
0450: 6c 65 20 6f 74 72 2d 6d 6f 64 65 20 5c 20 67 6c le otr-mode \ gl
0460: 6f 62 61 6c 20 6f 74 72 20 6d 6f 64 65 0a 0a 3a obal otr mode..:
0470: 20 3e 67 72 6f 75 70 20 28 20 61 64 64 72 20 75 >group ( addr u
0480: 20 2d 2d 20 29 0a 20 20 20 20 32 64 75 70 20 6d -- ). 2dup m
0490: 73 67 2d 67 72 6f 75 70 23 20 23 40 20 64 30 3d sg-group# #@ d0=
04a0: 20 49 46 0a 09 6e 65 74 32 6f 3a 6e 65 77 2d 6d IF..net2o:new-m
04b0: 73 67 20 3e 6f 20 32 64 75 70 20 74 6f 20 6d 73 sg >o 2dup to ms
04c0: 67 3a 6e 61 6d 65 24 0a 09 6f 74 72 2d 6d 6f 64 g:name$..otr-mod
04d0: 65 20 40 20 49 46 20 20 6d 73 67 3a 2b 6f 74 72 e @ IF msg:+otr
04e0: 20 20 54 48 45 4e 0a 09 6f 20 6f 3e 0a 09 63 65 THEN..o o>..ce
04f0: 6c 6c 2d 20 5b 20 6d 73 67 2d 63 6c 61 73 73 20 ll- [ msg-class
0500: 3e 6f 73 69 7a 65 20 40 20 63 65 6c 6c 2b 20 5d >osize @ cell+ ]
0510: 4c 0a 09 32 6f 76 65 72 20 6d 73 67 2d 67 72 6f L..2over msg-gro
0520: 75 70 23 20 23 21 0a 20 20 20 20 54 48 45 4e 20 up# #!. THEN
0530: 20 6c 61 73 74 23 20 63 65 6c 6c 2b 20 24 40 20 last# cell+ $@
0540: 64 72 6f 70 20 63 65 6c 6c 2b 20 74 6f 20 6d 73 drop cell+ to ms
0550: 67 2d 67 72 6f 75 70 2d 6f 0a 20 20 20 20 32 64 g-group-o. 2d
0560: 72 6f 70 20 3b 0a 0a 3a 20 61 76 61 6c 61 6e 63 rop ;..: avalanc
0570: 68 65 2d 6d 73 67 20 28 20 6d 73 67 20 75 31 20 he-msg ( msg u1
0580: 6f 3a 63 6f 6e 6e 65 63 74 20 2d 2d 20 29 0a 20 o:connect -- ).
0590: 20 20 20 5c 47 20 66 6f 72 77 61 72 64 20 6d 65 \G forward me
05a0: 73 73 61 67 65 20 74 6f 20 61 6c 6c 20 6e 65 78 ssage to all nex
05b0: 74 20 6e 6f 64 65 73 20 6f 66 20 74 68 61 74 20 t nodes of that
05c0: 6d 65 73 73 61 67 65 20 67 72 6f 75 70 0a 20 20 message group.
05d0: 20 20 7b 20 64 3a 20 6d 73 67 78 20 7d 0a 20 20 { d: msgx }.
05e0: 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d msg-group-o .m
05f0: 73 67 3a 70 65 65 72 73 5b 5d 20 24 40 0a 20 20 sg:peers[] $@.
0600: 20 20 62 6f 75 6e 64 73 20 3f 44 4f 20 20 49 20 bounds ?DO I
0610: 40 20 6f 20 3c 3e 20 49 46 20 20 6d 73 67 78 20 @ o <> IF msgx
0620: 49 20 40 20 2e 61 76 61 6c 61 6e 63 68 65 2d 74 I @ .avalanche-t
0630: 6f 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c o THEN. cell
0640: 20 2b 4c 4f 4f 50 20 3b 0a 0a 56 61 72 69 61 62 +LOOP ;..Variab
0650: 6c 65 20 6d 73 67 2d 67 72 6f 75 70 24 0a 55 73 le msg-group$.Us
0660: 65 72 20 72 65 70 6c 61 79 2d 6d 6f 64 65 0a 55 er replay-mode.U
0670: 73 65 72 20 73 6b 69 70 2d 73 69 67 3f 0a 0a 53 ser skip-sig?..S
0680: 65 6d 61 20 6d 73 67 6c 6f 67 2d 73 65 6d 61 0a ema msglog-sema.
0690: 0a 3a 20 3f 6d 73 67 2d 63 6f 6e 74 65 78 74 20 .: ?msg-context
06a0: 28 20 2d 2d 20 6f 20 29 0a 20 20 20 20 6d 73 67 ( -- o ). msg
06b0: 69 6e 67 2d 63 6f 6e 74 65 78 74 20 40 20 64 75 ing-context @ du
06c0: 70 20 30 3d 20 49 46 0a 09 64 72 6f 70 0a 09 6e p 0= IF..drop..n
06d0: 65 74 32 6f 3a 6e 65 77 2d 6d 73 67 69 6e 67 20 et2o:new-msging
06e0: 64 75 70 20 6d 73 67 69 6e 67 2d 63 6f 6e 74 65 dup msging-conte
06f0: 78 74 20 21 0a 20 20 20 20 54 48 45 4e 20 3b 0a xt !. THEN ;.
0700: 0a 3a 20 3e 63 68 61 74 69 64 20 28 20 67 72 6f .: >chatid ( gro
0710: 75 70 20 75 20 2d 2d 20 69 64 20 75 20 29 20 20 up u -- id u )
0720: 64 65 66 61 75 6c 74 6b 65 79 20 73 65 63 40 20 defaultkey sec@
0730: 6b 65 79 65 64 2d 68 61 73 68 23 31 32 38 20 3b keyed-hash#128 ;
0740: 0a 0a 3a 20 6d 73 67 2d 6c 6f 67 40 20 28 20 2d ..: msg-log@ ( -
0750: 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 5b - addr u ). [
0760: 3a 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d : msg-group-o .m
0770: 73 67 3a 6c 6f 67 5b 5d 20 24 40 20 73 61 76 65 sg:log[] $@ save
0780: 2d 6d 65 6d 20 3b 5d 20 6d 73 67 6c 6f 67 2d 73 -mem ;] msglog-s
0790: 65 6d 61 20 63 2d 73 65 63 74 69 6f 6e 20 3b 0a ema c-section ;.
07a0: 0a 3a 20 70 75 72 67 65 2d 6c 6f 67 20 28 20 2d .: purge-log ( -
07b0: 2d 20 29 0a 20 20 20 20 5b 3a 20 6d 73 67 2d 67 - ). [: msg-g
07c0: 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b roup-o .msg:log[
07d0: 5d 20 7b 20 61 5b 5d 20 7d 0a 09 30 20 20 42 45 ] { a[] }..0 BE
07e0: 47 49 4e 20 20 64 75 70 20 61 5b 5d 20 24 5b 5d GIN dup a[] $[]
07f0: 23 20 75 3c 20 20 57 48 49 4c 45 0a 09 09 64 75 # u< WHILE...du
0800: 70 20 61 5b 5d 20 24 5b 5d 40 20 63 68 65 63 6b p a[] $[]@ check
0810: 2d 64 61 74 65 20 6e 69 70 20 6e 69 70 20 49 46 -date nip nip IF
0820: 0a 09 09 20 20 20 20 64 75 70 20 61 5b 5d 20 24 ... dup a[] $
0830: 5b 5d 20 24 66 72 65 65 0a 09 09 20 20 20 20 61 [] $free... a
0840: 5b 5d 20 6f 76 65 72 20 63 65 6c 6c 73 20 63 65 [] over cells ce
0850: 6c 6c 20 24 64 65 6c 0a 09 09 45 4c 53 45 0a 09 ll $del...ELSE..
0860: 09 20 20 20 20 31 2b 0a 09 09 54 48 45 4e 0a 09 . 1+...THEN..
0870: 52 45 50 45 41 54 20 20 64 72 6f 70 20 3b 5d 20 REPEAT drop ;]
0880: 6d 73 67 6c 6f 67 2d 73 65 6d 61 20 63 2d 73 65 msglog-sema c-se
0890: 63 74 69 6f 6e 20 3b 0a 0a 3a 20 73 65 72 69 61 ction ;..: seria
08a0: 6c 69 7a 65 2d 6c 6f 67 20 28 20 61 64 64 72 20 lize-log ( addr
08b0: 75 20 2d 2d 20 24 61 64 64 72 20 29 0a 20 20 20 u -- $addr ).
08c0: 20 5b 3a 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 [: bounds ?DO..
08d0: 20 20 20 20 49 20 24 40 20 63 68 65 63 6b 2d 64 I $@ check-d
08e0: 61 74 65 20 30 3d 20 49 46 20 20 6e 65 74 32 6f ate 0= IF net2o
08f0: 2d 62 61 73 65 3a 24 2c 20 6e 65 74 32 6f 2d 62 -base:$, net2o-b
0900: 61 73 65 3a 6e 65 73 74 73 69 67 0a 09 20 20 20 ase:nestsig..
0910: 20 45 4c 53 45 20 20 20 6d 73 67 28 20 2e 22 20 ELSE msg( ."
0920: 72 65 6d 6f 76 65 64 20 65 6e 74 72 79 20 22 20 removed entry "
0930: 64 75 6d 70 20 29 65 6c 73 65 28 20 32 64 72 6f dump )else( 2dro
0940: 70 20 29 20 20 54 48 45 4e 0a 20 20 20 20 20 20 p ) THEN.
0950: 63 65 6c 6c 20 2b 4c 4f 4f 50 20 3b 5d 0a 20 20 cell +LOOP ;].
0960: 20 20 67 65 6e 2d 63 6d 64 20 3b 0a 0a 56 61 72 gen-cmd ;..Var
0970: 69 61 62 6c 65 20 73 61 76 65 64 2d 6d 73 67 24 iable saved-msg$
0980: 0a 36 34 56 61 72 69 61 62 6c 65 20 73 61 76 65 .64Variable save
0990: 64 2d 6d 73 67 2d 74 69 63 6b 73 0a 0a 3a 20 73 d-msg-ticks..: s
09a0: 61 76 65 2d 6d 73 67 73 20 28 20 67 72 6f 75 70 ave-msgs ( group
09b0: 2d 6f 20 2d 2d 20 29 20 74 6f 20 6d 73 67 2d 67 -o -- ) to msg-g
09c0: 72 6f 75 70 2d 6f 0a 20 20 20 20 6d 73 67 28 20 roup-o. msg(
09d0: 2e 22 20 53 61 76 65 20 6d 65 73 73 61 67 65 73 ." Save messages
09e0: 20 69 6e 20 67 72 6f 75 70 20 22 20 6d 73 67 2d in group " msg-
09f0: 67 72 6f 75 70 2d 6f 20 64 75 70 20 68 65 78 2e group-o dup hex.
0a00: 20 2e 6d 73 67 3a 6e 61 6d 65 24 20 74 79 70 65 .msg:name$ type
0a10: 20 63 72 20 29 0a 20 20 20 20 3f 2e 6e 65 74 32 cr ). ?.net2
0a20: 6f 2f 63 68 61 74 73 20 20 6e 65 74 32 6f 3a 6e o/chats net2o:n
0a30: 65 77 2d 6d 73 67 69 6e 67 20 3e 6f 0a 20 20 20 ew-msging >o.
0a40: 20 6d 73 67 2d 6c 6f 67 40 20 6f 76 65 72 20 3e msg-log@ over >
0a50: 72 20 20 73 65 72 69 61 6c 69 7a 65 2d 6c 6f 67 r serialize-log
0a60: 20 65 6e 63 2d 66 69 6c 65 20 24 21 62 75 66 0a enc-file $!buf.
0a70: 20 20 20 20 72 3e 20 66 72 65 65 20 74 68 72 6f r> free thro
0a80: 77 20 20 64 69 73 70 6f 73 65 20 6f 3e 0a 20 20 w dispose o>.
0a90: 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d msg-group-o .m
0aa0: 73 67 3a 6e 61 6d 65 24 20 3e 63 68 61 74 69 64 sg:name$ >chatid
0ab0: 20 2e 63 68 61 74 73 2f 20 65 6e 63 2d 66 69 6c .chats/ enc-fil
0ac0: 65 6e 61 6d 65 20 24 21 0a 20 20 20 20 70 6b 2d ename $!. pk-
0ad0: 6f 66 66 20 20 6b 65 79 2d 6c 69 73 74 20 65 6e off key-list en
0ae0: 63 66 69 6c 65 2d 72 65 73 74 20 3b 0a 0a 3a 20 cfile-rest ;..:
0af0: 73 61 76 65 2d 61 6c 6c 2d 6d 73 67 73 20 28 20 save-all-msgs (
0b00: 2d 2d 20 29 0a 20 20 20 20 73 61 76 65 64 2d 6d -- ). saved-m
0b10: 73 67 24 20 24 40 20 62 6f 75 6e 64 73 20 3f 44 sg$ $@ bounds ?D
0b20: 4f 20 20 49 20 40 20 73 61 76 65 2d 6d 73 67 73 O I @ save-msgs
0b30: 20 20 63 65 6c 6c 20 2b 4c 4f 4f 50 0a 20 20 20 cell +LOOP.
0b40: 20 73 61 76 65 64 2d 6d 73 67 24 20 24 66 72 65 saved-msg$ $fre
0b50: 65 20 3b 0a 0a 3a 20 73 61 76 65 2d 6d 73 67 73 e ;..: save-msgs
0b60: 3f 20 28 20 2d 2d 20 29 0a 20 20 20 20 73 61 76 ? ( -- ). sav
0b70: 65 64 2d 6d 73 67 2d 74 69 63 6b 73 20 36 34 40 ed-msg-ticks 64@
0b80: 20 74 69 63 6b 65 72 20 36 34 40 20 36 34 75 3c ticker 64@ 64u<
0b90: 3d 20 49 46 20 20 73 61 76 65 2d 61 6c 6c 2d 6d = IF save-all-m
0ba0: 73 67 73 0a 09 74 69 63 6b 73 20 63 6f 6e 66 69 sgs..ticks confi
0bb0: 67 3a 73 61 76 65 64 65 6c 74 61 26 20 32 40 20 g:savedelta& 2@
0bc0: 64 3e 36 34 20 36 34 2b 20 73 61 76 65 64 2d 6d d>64 64+ saved-m
0bd0: 73 67 2d 74 69 63 6b 73 20 36 34 21 20 20 54 48 sg-ticks 64! TH
0be0: 45 4e 20 3b 0a 0a 3a 20 6e 65 78 74 2d 73 61 76 EN ;..: next-sav
0bf0: 65 64 2d 6d 73 67 20 28 20 2d 2d 20 74 69 6d 65 ed-msg ( -- time
0c00: 20 29 0a 20 20 20 20 73 61 76 65 64 2d 6d 73 67 ). saved-msg
0c10: 2d 74 69 63 6b 73 20 36 34 40 20 36 34 64 75 70 -ticks 64@ 64dup
0c20: 20 36 34 23 30 20 36 34 3d 20 49 46 0a 09 36 34 64#0 64= IF..64
0c30: 64 72 6f 70 20 74 69 63 6b 73 20 36 34 64 75 70 drop ticks 64dup
0c40: 20 73 61 76 65 64 2d 6d 73 67 2d 74 69 63 6b 73 saved-msg-ticks
0c50: 20 36 34 21 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 64! THEN ;..:
0c60: 6d 73 67 2d 65 76 61 6c 20 28 20 61 64 64 72 20 msg-eval ( addr
0c70: 75 20 2d 2d 20 29 0a 20 20 20 20 6e 65 74 32 6f u -- ). net2o
0c80: 3a 6e 65 77 2d 6d 73 67 69 6e 67 20 3e 6f 20 30 :new-msging >o 0
0c90: 20 74 6f 20 70 61 72 65 6e 74 20 64 6f 2d 63 6d to parent do-cm
0ca0: 64 2d 6c 6f 6f 70 20 64 69 73 70 6f 73 65 20 6f d-loop dispose o
0cb0: 3e 20 3b 0a 0a 3a 20 6c 6f 61 64 2d 6d 73 67 20 > ;..: load-msg
0cc0: 28 20 67 72 6f 75 70 20 75 20 2d 2d 20 29 20 20 ( group u -- )
0cd0: 32 64 75 70 20 3e 67 72 6f 75 70 0a 20 20 20 20 2dup >group.
0ce0: 3e 63 68 61 74 69 64 20 2e 63 68 61 74 73 2f 20 >chatid .chats/
0cf0: 5b 3a 20 74 79 70 65 20 2e 22 20 2e 76 32 6f 22 [: type ." .v2o"
0d00: 20 3b 5d 20 24 74 6d 70 0a 20 20 20 20 32 64 75 ;] $tmp. 2du
0d10: 70 20 66 69 6c 65 2d 73 74 61 74 75 73 20 6e 69 p file-status ni
0d20: 70 20 6e 6f 2d 66 69 6c 65 23 20 3d 20 49 46 20 p no-file# = IF
0d30: 20 32 64 72 6f 70 20 45 58 49 54 20 20 54 48 45 2drop EXIT THE
0d40: 4e 0a 20 20 20 20 72 65 70 6c 61 79 2d 6d 6f 64 N. replay-mod
0d50: 65 20 6f 6e 20 20 73 6b 69 70 2d 73 69 67 3f 20 e on skip-sig?
0d60: 6f 6e 0a 20 20 20 20 5b 27 5d 20 64 65 63 72 79 on. ['] decry
0d70: 70 74 40 20 63 61 74 63 68 0a 20 20 20 20 3f 64 pt@ catch. ?d
0d80: 75 70 2d 49 46 20 20 44 6f 45 72 72 6f 72 20 32 up-IF DoError 2
0d90: 64 72 6f 70 0a 09 5c 20 74 72 79 20 72 65 61 64 drop..\ try read
0da0: 20 62 61 63 6b 75 70 20 69 6e 73 74 65 61 64 0a backup instead.
0db0: 09 5b 3a 20 65 6e 63 2d 66 69 6c 65 6e 61 6d 65 .[: enc-filename
0dc0: 20 24 2e 20 27 7e 27 20 65 6d 69 74 20 3b 5d 20 $. '~' emit ;]
0dd0: 24 74 6d 70 20 5b 27 5d 20 64 65 63 72 79 70 74 $tmp ['] decrypt
0de0: 40 20 63 61 74 63 68 0a 09 3f 64 75 70 2d 49 46 @ catch..?dup-IF
0df0: 20 20 44 6f 45 72 72 6f 72 20 32 64 72 6f 70 0a DoError 2drop.
0e00: 09 45 4c 53 45 20 20 6d 73 67 2d 65 76 61 6c 20 .ELSE msg-eval
0e10: 20 54 48 45 4e 0a 20 20 20 20 45 4c 53 45 20 20 THEN. ELSE
0e20: 6d 73 67 2d 65 76 61 6c 20 20 54 48 45 4e 0a 20 msg-eval THEN.
0e30: 20 20 20 72 65 70 6c 61 79 2d 6d 6f 64 65 20 6f replay-mode o
0e40: 66 66 20 20 73 6b 69 70 2d 73 69 67 3f 20 6f 66 ff skip-sig? of
0e50: 66 20 20 65 6e 63 2d 66 69 6c 65 20 24 66 72 65 f enc-file $fre
0e60: 65 20 3b 0a 0a 65 76 65 6e 74 3a 20 3a 3e 73 61 e ;..event: :>sa
0e70: 76 65 2d 6d 73 67 73 20 28 20 67 72 6f 75 70 2d ve-msgs ( group-
0e80: 6f 20 2d 2d 20 29 20 73 61 76 65 64 2d 6d 73 67 o -- ) saved-msg
0e90: 24 20 2b 75 6e 69 71 75 65 24 20 3b 0a 65 76 65 $ +unique$ ;.eve
0ea0: 6e 74 3a 20 3a 3e 73 61 76 65 2d 61 6c 6c 2d 6d nt: :>save-all-m
0eb0: 73 67 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 73 sgs ( -- ). s
0ec0: 61 76 65 2d 61 6c 6c 2d 6d 73 67 73 20 3b 0a 65 ave-all-msgs ;.e
0ed0: 76 65 6e 74 3a 20 3a 3e 6c 6f 61 64 2d 6d 73 67 vent: :>load-msg
0ee0: 20 28 20 67 72 6f 75 70 2d 6f 20 2d 2d 20 29 0a ( group-o -- ).
0ef0: 20 20 20 20 2e 6d 73 67 3a 6e 61 6d 65 24 20 6c .msg:name$ l
0f00: 6f 61 64 2d 6d 73 67 20 3b 0a 0a 3a 20 3e 6c 6f oad-msg ;..: >lo
0f10: 61 64 2d 67 72 6f 75 70 20 28 20 67 72 6f 75 70 ad-group ( group
0f20: 20 75 20 2d 2d 20 29 0a 20 20 20 20 3e 67 72 6f u -- ). >gro
0f30: 75 70 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e up msg-group-o .
0f40: 6d 73 67 3a 6c 6f 67 5b 5d 20 24 40 6c 65 6e 20 msg:log[] $@len
0f50: 30 3d 0a 20 20 20 20 49 46 20 20 3c 65 76 65 6e 0=. IF <even
0f60: 74 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 65 6c t msg-group-o el
0f70: 69 74 2c 20 3a 3e 6c 6f 61 64 2d 6d 73 67 0a 09 it, :>load-msg..
0f80: 70 61 72 65 6e 74 20 2e 77 61 69 74 2d 74 61 73 parent .wait-tas
0f90: 6b 20 40 0a 09 64 75 70 20 30 3d 20 49 46 20 20 k @..dup 0= IF
0fa0: 64 72 6f 70 20 3f 66 69 6c 65 2d 74 61 73 6b 20 drop ?file-task
0fb0: 20 54 48 45 4e 20 20 65 76 65 6e 74 3e 20 20 54 THEN event> T
0fc0: 48 45 4e 20 3b 0a 0a 3a 20 21 73 61 76 65 2d 61 HEN ;..: !save-a
0fd0: 6c 6c 2d 6d 73 67 73 20 28 20 2d 2d 20 29 0a 20 ll-msgs ( -- ).
0fe0: 20 20 20 73 79 6e 63 66 69 6c 65 28 20 73 61 76 syncfile( sav
0ff0: 65 2d 61 6c 6c 2d 6d 73 67 73 20 29 65 6c 73 65 e-all-msgs )else
1000: 28 0a 20 20 20 20 3c 65 76 65 6e 74 20 3a 3e 73 (. <event :>s
1010: 61 76 65 2d 61 6c 6c 2d 6d 73 67 73 20 3f 66 69 ave-all-msgs ?fi
1020: 6c 65 2d 74 61 73 6b 20 65 76 65 6e 74 7c 20 29 le-task event| )
1030: 20 3b 0a 0a 3a 20 73 61 76 65 2d 6d 73 67 73 26 ;..: save-msgs&
1040: 20 28 20 2d 2d 20 29 0a 20 20 20 20 73 79 6e 63 ( -- ). sync
1050: 66 69 6c 65 28 20 6d 73 67 2d 67 72 6f 75 70 2d file( msg-group-
1060: 6f 20 73 61 76 65 64 2d 6d 73 67 24 20 2b 75 6e o saved-msg$ +un
1070: 69 71 75 65 24 20 29 65 6c 73 65 28 0a 20 20 20 ique$ )else(.
1080: 20 3c 65 76 65 6e 74 20 6d 73 67 2d 67 72 6f 75 <event msg-grou
1090: 70 2d 6f 20 65 6c 69 74 2c 20 3a 3e 73 61 76 65 p-o elit, :>save
10a0: 2d 6d 73 67 73 20 3f 66 69 6c 65 2d 74 61 73 6b -msgs ?file-task
10b0: 20 65 76 65 6e 74 3e 20 29 20 3b 0a 0a 30 20 56 event> ) ;..0 V
10c0: 61 6c 75 65 20 6c 6f 67 23 0a 32 56 61 72 69 61 alue log#.2Varia
10d0: 62 6c 65 20 6c 61 73 74 2d 6d 73 67 0a 0a 3a 20 ble last-msg..:
10e0: 2b 6d 73 67 2d 6c 6f 67 20 28 20 61 64 64 72 20 +msg-log ( addr
10f0: 75 20 2d 2d 20 61 64 64 72 27 20 75 27 20 2f 20 u -- addr' u' /
1100: 30 20 30 20 29 0a 20 20 20 20 5b 3a 20 6d 73 67 0 0 ). [: msg
1110: 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f -group-o .msg:lo
1120: 67 5b 5d 20 24 69 6e 73 5b 5d 64 61 74 65 20 20 g[] $ins[]date
1130: 64 75 70 20 20 64 75 70 20 30 3c 20 78 6f 72 20 dup dup 0< xor
1140: 74 6f 20 6c 6f 67 23 0a 09 6c 6f 67 23 20 6d 73 to log#..log# ms
1150: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c g-group-o .msg:l
1160: 6f 67 5b 5d 20 24 5b 5d 40 20 6c 61 73 74 2d 6d og[] $[]@ last-m
1170: 73 67 20 32 21 0a 09 30 3c 20 49 46 20 20 23 30 sg 2!..0< IF #0
1180: 2e 20 20 45 4c 53 45 20 20 6c 61 73 74 2d 6d 73 . ELSE last-ms
1190: 67 20 32 40 20 20 54 48 45 4e 0a 20 20 20 20 3b g 2@ THEN. ;
11a0: 5d 20 6d 73 67 6c 6f 67 2d 73 65 6d 61 20 63 2d ] msglog-sema c-
11b0: 73 65 63 74 69 6f 6e 20 3b 0a 3a 20 3f 73 61 76 section ;.: ?sav
11c0: 65 2d 6d 73 67 20 28 20 2d 2d 20 29 0a 20 20 20 e-msg ( -- ).
11d0: 20 6d 73 67 28 20 2e 22 20 73 61 76 69 6e 67 20 msg( ." saving
11e0: 6d 65 73 73 61 67 65 73 20 69 6e 20 67 72 6f 75 messages in grou
11f0: 70 20 22 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 p " msg-group-o
1200: 64 75 70 20 68 65 78 2e 20 2e 6d 73 67 3a 6e 61 dup hex. .msg:na
1210: 6d 65 24 20 74 79 70 65 20 63 72 20 29 0a 20 20 me$ type cr ).
1220: 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d msg-group-o .m
1230: 73 67 3a 3f 6f 74 72 20 72 65 70 6c 61 79 2d 6d sg:?otr replay-m
1240: 6f 64 65 20 40 20 6f 72 20 30 3d 20 49 46 20 20 ode @ or 0= IF
1250: 73 61 76 65 2d 6d 73 67 73 26 20 20 54 48 45 4e save-msgs& THEN
1260: 20 3b 0a 0a 53 65 6d 61 20 71 75 65 75 65 2d 73 ;..Sema queue-s
1270: 65 6d 61 0a 0a 5c 20 70 65 65 72 20 71 75 65 75 ema..\ peer queu
1280: 65 2c 20 69 6e 20 6d 73 67 20 63 6f 6e 74 65 78 e, in msg contex
1290: 74 0a 0a 3a 20 70 65 65 72 3e 20 28 20 2d 2d 20 t..: peer> ( --
12a0: 61 64 64 72 20 2f 20 30 20 29 0a 20 20 20 20 5b addr / 0 ). [
12b0: 3a 20 6d 73 67 3a 70 65 65 72 73 5b 5d 20 62 61 : msg:peers[] ba
12c0: 63 6b 3e 20 3b 5d 20 71 75 65 75 65 2d 73 65 6d ck> ;] queue-sem
12d0: 61 20 63 2d 73 65 63 74 69 6f 6e 20 3b 0a 3a 20 a c-section ;.:
12e0: 3e 70 65 65 72 20 28 20 61 64 64 72 20 75 20 2d >peer ( addr u -
12f0: 2d 20 29 0a 20 20 20 20 5b 3a 20 6d 73 67 3a 70 - ). [: msg:p
1300: 65 65 72 73 5b 5d 20 24 2b 5b 5d 21 20 3b 5d 20 eers[] $+[]! ;]
1310: 71 75 65 75 65 2d 73 65 6d 61 20 63 2d 73 65 63 queue-sema c-sec
1320: 74 69 6f 6e 20 3b 0a 0a 5c 20 65 76 65 6e 74 73 tion ;..\ events
1330: 0a 0a 6d 73 67 2d 63 6c 61 73 73 20 63 6c 61 73 ..msg-class clas
1340: 73 20 65 6e 64 2d 63 6c 61 73 73 20 6d 73 67 2d s end-class msg-
1350: 6e 6f 74 69 66 79 2d 63 6c 61 73 73 0a 0a 6d 73 notify-class..ms
1360: 67 2d 6e 6f 74 69 66 79 2d 63 6c 61 73 73 20 27 g-notify-class '
1370: 20 6e 65 77 20 73 74 61 74 69 63 2d 61 20 77 69 new static-a wi
1380: 74 68 2d 61 6c 6c 6f 63 61 74 65 72 20 43 6f 6e th-allocater Con
1390: 73 74 61 6e 74 20 6d 73 67 2d 6e 6f 74 69 66 79 stant msg-notify
13a0: 2d 6f 0a 0a 3a 20 3e 6d 73 67 2d 6c 6f 67 20 28 -o..: >msg-log (
13b0: 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 27 addr u -- addr'
13c0: 20 75 20 29 0a 20 20 20 20 2b 6d 73 67 2d 6c 6f u ). +msg-lo
13d0: 67 20 3f 73 61 76 65 2d 6d 73 67 20 3b 0a 0a 3a g ?save-msg ;..:
13e0: 20 64 6f 2d 6d 73 67 2d 6e 65 73 74 73 69 67 20 do-msg-nestsig
13f0: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 ( addr u -- ).
1400: 20 20 32 64 75 70 20 6d 73 67 2d 67 72 6f 75 70 2dup msg-group
1410: 2d 6f 20 2e 6d 73 67 3a 64 69 73 70 6c 61 79 0a -o .msg:display.
1420: 20 20 20 20 6d 73 67 2d 6e 6f 74 69 66 79 2d 6f msg-notify-o
1430: 20 2e 6d 73 67 3a 64 69 73 70 6c 61 79 20 3b 0a .msg:display ;.
1440: 0a 3a 20 64 69 73 70 6c 61 79 2d 6c 61 73 74 6e .: display-lastn
1450: 20 28 20 6e 20 2d 2d 20 29 0a 20 20 20 20 6d 73 ( n -- ). ms
1460: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 72 g-group-o .msg:r
1470: 65 64 69 73 70 6c 61 79 20 3b 0a 3a 20 64 69 73 edisplay ;.: dis
1480: 70 6c 61 79 2d 73 79 6e 63 2d 64 6f 6e 65 20 28 play-sync-done (
1490: 20 2d 2d 20 29 0a 20 20 20 20 72 6f 77 73 20 20 -- ). rows
14a0: 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 msg-group-o .msg
14b0: 3a 72 65 64 69 73 70 6c 61 79 20 3b 0a 0a 3a 20 :redisplay ;..:
14c0: 64 69 73 70 6c 61 79 2d 6f 6e 65 2d 6d 73 67 20 display-one-msg
14d0: 7b 20 64 3a 20 6d 73 67 74 20 2d 2d 20 7d 0a 20 { d: msgt -- }.
14e0: 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 3e msg-group-o >
14f0: 6f 0a 20 20 20 20 6d 73 67 74 20 5b 27 5d 20 6d o. msgt ['] m
1500: 73 67 3a 64 69 73 70 6c 61 79 20 63 61 74 63 68 sg:display catch
1510: 20 49 46 20 20 2e 22 20 69 6e 76 61 6c 69 64 20 IF ." invalid
1520: 65 6e 74 72 79 22 20 20 63 72 20 20 32 64 72 6f entry" cr 2dro
1530: 70 20 20 54 48 45 4e 0a 20 20 20 20 6f 3e 20 3b p THEN. o> ;
1540: 0a 0a 46 6f 72 77 61 72 64 20 73 69 6c 65 6e 74 ..Forward silent
1550: 2d 6a 6f 69 6e 0a 0a 5c 20 21 21 46 49 58 4d 45 -join..\ !!FIXME
1560: 21 21 20 73 68 6f 75 6c 64 20 75 73 65 20 61 6e !! should use an
1570: 20 61 73 79 6e 63 68 72 6f 6e 6f 75 73 20 22 64 asynchronous "d
1580: 6f 2d 77 68 65 6e 2d 63 6f 6e 6e 65 63 74 65 64 o-when-connected
1590: 22 20 74 68 69 6e 67 0a 0a 3a 20 2b 75 6e 69 71 " thing..: +uniq
15a0: 75 65 2d 63 6f 6e 20 28 20 2d 2d 20 29 20 6f 20 ue-con ( -- ) o
15b0: 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 msg-group-o .msg
15c0: 3a 70 65 65 72 73 5b 5d 20 2b 75 6e 69 71 75 65 :peers[] +unique
15d0: 24 20 3b 0a 46 6f 72 77 61 72 64 20 2b 63 68 61 $ ;.Forward +cha
15e0: 74 2d 63 6f 6e 74 72 6f 6c 0a 0a 3a 20 63 68 61 t-control..: cha
15f0: 74 2d 73 69 6c 65 6e 74 2d 6a 6f 69 6e 20 28 20 t-silent-join (
1600: 2d 2d 20 29 0a 20 20 20 20 72 65 63 6f 6e 6e 65 -- ). reconne
1610: 63 74 28 20 2e 22 20 73 69 6c 65 6e 74 20 6a 6f ct( ." silent jo
1620: 69 6e 20 22 20 6f 20 68 65 78 2e 20 63 6f 6e 6e in " o hex. conn
1630: 65 63 74 69 6f 6e 20 68 65 78 2e 20 63 72 20 29 ection hex. cr )
1640: 0a 20 20 20 20 6f 20 74 6f 20 63 6f 6e 6e 65 63 . o to connec
1650: 74 69 6f 6e 0a 20 20 20 20 3f 6d 73 67 2d 63 6f tion. ?msg-co
1660: 6e 74 65 78 74 20 3e 6f 20 73 69 6c 65 6e 74 2d ntext >o silent-
1670: 6c 61 73 74 23 20 40 20 74 6f 20 6c 61 73 74 23 last# @ to last#
1680: 20 6f 3e 0a 20 20 20 20 72 65 63 6f 6e 6e 65 63 o>. reconnec
1690: 74 28 20 2e 22 20 6a 6f 69 6e 3a 20 22 20 6c 61 t( ." join: " la
16a0: 73 74 23 20 24 2e 20 63 72 20 29 0a 20 20 20 20 st# $. cr ).
16b0: 2b 75 6e 69 71 75 65 2d 63 6f 6e 20 73 69 6c 65 +unique-con sile
16c0: 6e 74 2d 6a 6f 69 6e 20 3b 0a 0a 3a 20 63 68 61 nt-join ;..: cha
16d0: 74 2d 73 69 6c 65 6e 74 2d 72 71 64 20 28 20 6e t-silent-rqd ( n
16e0: 20 2d 2d 20 29 0a 20 20 20 20 72 65 63 6f 6e 6e -- ). reconn
16f0: 65 63 74 28 20 2e 22 20 73 69 6c 65 6e 74 20 72 ect( ." silent r
1700: 65 71 75 73 74 22 20 63 72 20 29 0a 20 20 20 20 equst" cr ).
1710: 63 6c 65 61 6e 2d 72 65 71 75 65 73 74 20 63 68 clean-request ch
1720: 61 74 2d 73 69 6c 65 6e 74 2d 6a 6f 69 6e 20 3b at-silent-join ;
1730: 0a 0a 3a 20 3f 6e 61 74 20 28 20 2d 2d 20 29 20 ..: ?nat ( -- )
1740: 20 6f 20 74 6f 20 63 6f 6e 6e 65 63 74 69 6f 6e o to connection
1750: 0a 20 20 20 20 6e 65 74 32 6f 2d 63 6f 64 65 20 . net2o-code
1760: 6e 61 74 2d 70 75 6e 63 68 20 65 6e 64 2d 63 6f nat-punch end-co
1770: 64 65 20 3b 0a 0a 3a 20 3f 63 68 61 74 2d 6e 61 de ;..: ?chat-na
1780: 74 20 28 20 2d 2d 20 29 0a 20 20 20 20 5b 27 5d t ( -- ). [']
1790: 20 63 68 61 74 2d 73 69 6c 65 6e 74 2d 72 71 64 chat-silent-rqd
17a0: 20 72 71 64 21 20 3f 6e 61 74 20 3b 0a 0a 3a 20 rqd! ?nat ;..:
17b0: 63 68 61 74 2d 72 71 64 2d 6e 61 74 20 28 20 6e chat-rqd-nat ( n
17c0: 20 2d 2d 20 29 0a 20 20 20 20 72 65 63 6f 6e 6e -- ). reconn
17d0: 65 63 74 28 20 2e 22 20 63 68 61 74 20 72 65 71 ect( ." chat req
17e0: 20 64 6f 6e 65 2c 20 73 74 61 72 74 20 6e 61 74 done, start nat
17f0: 20 74 72 61 76 65 72 73 61 6c 22 20 63 72 20 29 traversal" cr )
1800: 0a 20 20 20 20 63 6f 6e 6e 65 63 74 2d 72 65 73 . connect-res
1810: 74 20 20 2b 66 6c 6f 77 2d 63 6f 6e 74 72 6f 6c t +flow-control
1820: 20 2b 72 65 73 65 6e 64 20 3f 63 68 61 74 2d 6e +resend ?chat-n
1830: 61 74 20 3b 0a 0a 3a 20 63 68 61 74 2d 72 71 64 at ;..: chat-rqd
1840: 2d 6e 6f 6e 61 74 20 28 20 6e 20 2d 2d 20 29 0a -nonat ( n -- ).
1850: 20 20 20 20 72 65 63 6f 6e 6e 65 63 74 28 20 2e reconnect( .
1860: 22 20 63 68 61 74 20 72 65 71 20 64 6f 6e 65 2c " chat req done,
1870: 20 73 74 61 72 74 20 73 69 6c 65 6e 74 20 6a 6f start silent jo
1880: 69 6e 22 20 63 72 20 29 0a 20 20 20 20 63 6f 6e in" cr ). con
1890: 6e 65 63 74 2d 72 65 73 74 20 20 2b 66 6c 6f 77 nect-rest +flow
18a0: 2d 63 6f 6e 74 72 6f 6c 20 2b 72 65 73 65 6e 64 -control +resend
18b0: 20 63 68 61 74 2d 73 69 6c 65 6e 74 2d 6a 6f 69 chat-silent-joi
18c0: 6e 20 3b 0a 0a 55 73 65 72 20 70 65 65 72 2d 62 n ;..User peer-b
18d0: 75 66 0a 0a 3a 20 72 65 63 6f 6e 6e 65 63 74 2d uf..: reconnect-
18e0: 63 68 61 74 20 28 20 61 64 64 72 20 75 20 24 63 chat ( addr u $c
18f0: 68 61 74 20 2d 2d 20 29 0a 20 20 20 20 70 65 65 hat -- ). pee
1900: 72 2d 62 75 66 20 24 21 62 75 66 20 20 6c 61 73 r-buf $!buf las
1910: 74 23 20 70 65 65 72 2d 62 75 66 20 24 40 0a 20 t# peer-buf $@.
1920: 20 20 20 72 65 63 6f 6e 6e 65 63 74 28 20 2e 22 reconnect( ."
1930: 20 72 65 63 6f 6e 6e 65 63 74 20 22 20 32 64 75 reconnect " 2du
1940: 70 20 32 64 75 70 20 2b 20 31 2d 20 63 40 20 31 p 2dup + 1- c@ 1
1950: 2b 20 2d 20 2e 61 64 64 72 24 20 63 72 20 29 0a + - .addr$ cr ).
1960: 20 20 20 20 72 65 63 6f 6e 6e 65 63 74 28 20 2e reconnect( .
1970: 22 20 69 6e 20 67 72 6f 75 70 3a 20 22 20 6c 61 " in group: " la
1980: 73 74 23 20 64 75 70 20 68 65 78 2e 20 24 2e 20 st# dup hex. $.
1990: 63 72 20 29 0a 20 20 20 20 30 20 3e 6f 20 24 41 cr ). 0 >o $A
19a0: 20 24 41 20 5b 3a 20 72 65 63 6f 6e 6e 65 63 74 $A [: reconnect
19b0: 28 20 2e 22 20 70 72 65 70 61 72 65 20 72 65 63 ( ." prepare rec
19c0: 6f 6e 6e 65 63 74 69 6f 6e 22 20 63 72 20 29 0a onnection" cr ).
19d0: 20 20 20 20 20 20 3f 6d 73 67 2d 63 6f 6e 74 65 ?msg-conte
19e0: 78 74 20 3e 6f 20 73 69 6c 65 6e 74 2d 6c 61 73 xt >o silent-las
19f0: 74 23 20 21 20 6f 3e 0a 20 20 20 20 20 20 5b 27 t# ! o>. ['
1a00: 5d 20 63 68 61 74 2d 72 71 64 2d 6e 61 74 20 5b ] chat-rqd-nat [
1a10: 27 5d 20 63 68 61 74 2d 72 71 64 2d 6e 6f 6e 61 '] chat-rqd-nona
1a20: 74 20 69 6e 64 2d 61 64 64 72 20 40 20 73 65 6c t ind-addr @ sel
1a30: 65 63 74 20 72 71 64 21 20 3b 5d 0a 20 20 20 20 ect rqd! ;].
1a40: 61 64 64 72 2d 63 6f 6e 6e 65 63 74 20 32 64 75 addr-connect 2du
1a50: 70 20 64 30 3d 20 49 46 20 20 32 64 72 6f 70 20 p d0= IF 2drop
1a60: 20 45 4c 53 45 20 20 61 76 61 6c 61 6e 63 68 65 ELSE avalanche
1a70: 2d 74 6f 20 20 54 48 45 4e 20 6f 3e 20 3b 0a 0a -to THEN o> ;..
1a80: 65 76 65 6e 74 3a 20 3a 3e 61 76 61 6c 61 6e 63 event: :>avalanc
1a90: 68 65 20 28 20 61 64 64 72 20 75 20 6f 20 67 72 he ( addr u o gr
1aa0: 6f 75 70 20 2d 2d 20 29 0a 20 20 20 20 61 76 61 oup -- ). ava
1ab0: 6c 61 6e 63 68 65 28 20 2e 22 20 41 76 61 6c 61 lanche( ." Avala
1ac0: 6e 63 68 65 20 74 6f 3a 20 22 20 64 75 70 20 68 nche to: " dup h
1ad0: 65 78 2e 20 63 72 20 29 0a 20 20 20 20 74 6f 20 ex. cr ). to
1ae0: 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 61 76 61 msg-group-o .ava
1af0: 6c 61 6e 63 68 65 2d 6d 73 67 20 3b 0a 65 76 65 lanche-msg ;.eve
1b00: 6e 74 3a 20 3a 3e 63 68 61 74 2d 72 65 63 6f 6e nt: :>chat-recon
1b10: 6e 65 63 74 20 28 20 61 64 64 72 20 75 20 24 63 nect ( addr u $c
1b20: 68 61 74 20 6f 20 67 72 6f 75 70 20 2d 2d 20 29 hat o group -- )
1b30: 0a 20 20 20 20 74 6f 20 6d 73 67 2d 67 72 6f 75 . to msg-grou
1b40: 70 2d 6f 20 2e 72 65 63 6f 6e 6e 65 63 74 2d 63 p-o .reconnect-c
1b50: 68 61 74 20 3b 0a 65 76 65 6e 74 3a 20 3a 3e 6d hat ;.event: :>m
1b60: 73 67 2d 6e 65 73 74 73 69 67 20 28 20 24 61 64 sg-nestsig ( $ad
1b70: 64 72 20 6f 20 67 72 6f 75 70 20 2d 2d 20 29 0a dr o group -- ).
1b80: 20 20 20 20 74 6f 20 6d 73 67 2d 67 72 6f 75 70 to msg-group
1b90: 2d 6f 20 3e 6f 20 7b 20 77 5e 20 6d 20 7d 20 6d -o >o { w^ m } m
1ba0: 20 24 40 20 64 6f 2d 6d 73 67 2d 6e 65 73 74 73 $@ do-msg-nests
1bb0: 69 67 20 6d 20 24 66 72 65 65 20 6f 3e 0a 20 20 ig m $free o>.
1bc0: 20 20 63 74 72 6c 20 4c 20 69 6e 73 6b 65 79 20 ctrl L inskey
1bd0: 3b 0a 0a 5c 20 63 6f 6f 72 64 69 6e 61 74 65 73 ;..\ coordinates
1be0: 0a 0a 36 20 73 66 6c 6f 61 74 73 20 62 75 66 66 ..6 sfloats buff
1bf0: 65 72 3a 20 63 6f 6f 72 64 22 0a 39 30 65 20 63 er: coord".90e c
1c00: 6f 6f 72 64 22 20 73 66 6c 6f 61 74 2b 20 73 66 oord" sfloat+ sf
1c10: 21 0a 3a 20 63 6f 6f 72 64 40 20 28 20 2d 2d 20 !.: coord@ ( --
1c20: 61 64 64 72 20 75 20 29 20 63 6f 6f 72 64 22 20 addr u ) coord"
1c30: 36 20 73 66 6c 6f 61 74 73 20 3b 0a 3a 20 73 66 6 sfloats ;.: sf
1c40: 5b 5d 40 20 28 20 61 64 64 72 20 69 20 2d 2d 20 []@ ( addr i --
1c50: 73 66 20 29 20 20 73 66 6c 6f 61 74 73 20 2b 20 sf ) sfloats +
1c60: 73 66 40 20 3b 0a 3a 20 73 66 5b 5d 21 20 28 20 sf@ ;.: sf[]! (
1c70: 61 64 64 72 20 69 20 2d 2d 20 73 66 20 29 20 20 addr i -- sf )
1c80: 73 66 6c 6f 61 74 73 20 2b 20 73 66 21 20 3b 0a sfloats + sf! ;.
1c90: 0a 5b 49 46 44 45 46 5d 20 61 6e 64 72 6f 69 64 .[IFDEF] android
1ca0: 0a 20 20 20 20 72 65 71 75 69 72 65 20 75 6e 69 . require uni
1cb0: 78 2f 6a 6e 69 2d 6c 6f 63 61 74 69 6f 6e 2e 66 x/jni-location.f
1cc0: 73 0a 20 20 20 20 61 6c 73 6f 20 61 6e 64 72 6f s. also andro
1cd0: 69 64 0a 20 20 20 20 3a 20 63 6f 6f 72 64 21 20 id. : coord!
1ce0: 28 20 2d 2d 20 29 20 6c 6f 63 61 74 69 6f 6e 20 ( -- ) location
1cf0: 3f 64 75 70 2d 49 46 20 20 3e 6f 0a 09 20 20 20 ?dup-IF >o..
1d00: 20 67 65 74 4c 61 74 69 74 75 64 65 20 20 63 6f getLatitude co
1d10: 6f 72 64 22 20 30 20 73 66 5b 5d 21 0a 09 20 20 ord" 0 sf[]!..
1d20: 20 20 67 65 74 4c 6f 6e 67 69 74 75 64 65 20 63 getLongitude c
1d30: 6f 6f 72 64 22 20 31 20 73 66 5b 5d 21 0a 09 20 oord" 1 sf[]!..
1d40: 20 20 20 67 65 74 41 6c 74 69 74 75 64 65 20 20 getAltitude
1d50: 63 6f 6f 72 64 22 20 32 20 73 66 5b 5d 21 0a 09 coord" 2 sf[]!..
1d60: 20 20 20 20 67 65 74 53 70 65 65 64 20 20 20 20 getSpeed
1d70: 20 63 6f 6f 72 64 22 20 33 20 73 66 5b 5d 21 0a coord" 3 sf[]!.
1d80: 09 20 20 20 20 67 65 74 42 65 61 72 69 6e 67 20 . getBearing
1d90: 20 20 63 6f 6f 72 64 22 20 34 20 73 66 5b 5d 21 coord" 4 sf[]!
1da0: 0a 09 20 20 20 20 67 65 74 41 63 63 75 72 61 63 .. getAccurac
1db0: 79 20 20 63 6f 6f 72 64 22 20 35 20 73 66 5b 5d y coord" 5 sf[]
1dc0: 21 0a 09 20 20 20 20 6f 3e 0a 09 45 4c 53 45 0a !.. o>..ELSE.
1dd0: 09 20 20 20 20 73 74 61 72 74 2d 67 70 73 0a 09 . start-gps..
1de0: 54 48 45 4e 20 3b 0a 20 20 20 20 3a 6e 6f 6e 61 THEN ;. :nona
1df0: 6d 65 20 6c 65 76 65 6c 23 20 40 20 30 3e 20 49 me level# @ 0> I
1e00: 46 20 20 2d 31 20 6c 65 76 65 6c 23 20 2b 21 0a F -1 level# +!.
1e10: 09 45 4c 53 45 20 20 63 74 72 6c 20 55 20 69 6e .ELSE ctrl U in
1e20: 73 6b 65 79 20 63 74 72 6c 20 44 20 69 6e 73 6b skey ctrl D insk
1e30: 65 79 20 54 48 45 4e 20 3b 20 69 73 20 61 62 61 ey THEN ; is aba
1e40: 63 6b 0a 20 20 20 20 70 72 65 76 69 6f 75 73 0a ck. previous.
1e50: 5b 45 4c 53 45 5d 0a 20 20 20 20 5b 49 46 44 45 [ELSE]. [IFDE
1e60: 46 5d 20 68 61 73 2d 67 70 73 64 3f 0a 09 73 22 F] has-gpsd?..s"
1e70: 20 75 6e 69 78 2f 67 70 73 6c 69 62 2e 66 73 22 unix/gpslib.fs"
1e80: 20 27 20 72 65 71 75 69 72 65 64 20 63 61 74 63 ' required catc
1e90: 68 20 5b 49 46 5d 0a 09 20 20 20 20 32 64 72 6f h [IF].. 2dro
1ea0: 70 20 3a 20 63 6f 6f 72 64 21 20 3b 0a 09 5b 45 p : coord! ;..[E
1eb0: 4c 53 45 5d 0a 09 20 20 20 20 30 20 56 61 6c 75 LSE].. 0 Valu
1ec0: 65 20 67 70 73 2d 6f 70 65 6e 65 64 3f 0a 09 20 e gps-opened?..
1ed0: 20 20 20 3a 20 63 6f 6f 72 64 21 20 28 20 2d 2d : coord! ( --
1ee0: 20 29 20 67 70 73 2d 6f 70 65 6e 65 64 3f 20 30 ) gps-opened? 0
1ef0: 3d 20 49 46 0a 09 09 20 20 20 20 67 70 73 2d 6c = IF... gps-l
1f00: 6f 63 61 6c 2d 6f 70 65 6e 20 30 3d 20 74 6f 20 ocal-open 0= to
1f10: 67 70 73 2d 6f 70 65 6e 65 64 3f 0a 09 09 20 20 gps-opened?...
1f20: 20 20 67 70 73 2d 6f 70 65 6e 65 64 3f 20 30 3d gps-opened? 0=
1f30: 20 3f 45 58 49 54 0a 09 09 54 48 45 4e 0a 09 09 ?EXIT...THEN...
1f40: 67 70 73 2d 66 69 78 20 7b 20 66 69 78 20 7d 0a gps-fix { fix }.
1f50: 09 09 66 69 78 20 67 70 73 3a 67 70 73 5f 66 69 ..fix gps:gps_fi
1f60: 78 5f 74 2d 6c 61 74 69 74 75 64 65 20 20 64 66 x_t-latitude df
1f70: 40 20 63 6f 6f 72 64 22 20 30 20 73 66 5b 5d 21 @ coord" 0 sf[]!
1f80: 0a 09 09 66 69 78 20 67 70 73 3a 67 70 73 5f 66 ...fix gps:gps_f
1f90: 69 78 5f 74 2d 6c 6f 6e 67 69 74 75 64 65 20 64 ix_t-longitude d
1fa0: 66 40 20 63 6f 6f 72 64 22 20 31 20 73 66 5b 5d f@ coord" 1 sf[]
1fb0: 21 0a 09 09 66 69 78 20 67 70 73 3a 67 70 73 5f !...fix gps:gps_
1fc0: 66 69 78 5f 74 2d 61 6c 74 69 74 75 64 65 20 20 fix_t-altitude
1fd0: 64 66 40 20 63 6f 6f 72 64 22 20 32 20 73 66 5b df@ coord" 2 sf[
1fe0: 5d 21 0a 09 09 66 69 78 20 67 70 73 3a 67 70 73 ]!...fix gps:gps
1ff0: 5f 66 69 78 5f 74 2d 73 70 65 65 64 20 20 20 20 _fix_t-speed
2000: 20 64 66 40 20 63 6f 6f 72 64 22 20 33 20 73 66 df@ coord" 3 sf
2010: 5b 5d 21 0a 09 09 66 69 78 20 67 70 73 3a 67 70 []!...fix gps:gp
2020: 73 5f 66 69 78 5f 74 2d 74 72 61 63 6b 20 20 20 s_fix_t-track
2030: 20 20 64 66 40 20 63 6f 6f 72 64 22 20 34 20 73 df@ coord" 4 s
2040: 66 5b 5d 21 0a 09 09 66 69 78 20 67 70 73 3a 67 f[]!...fix gps:g
2050: 70 73 5f 66 69 78 5f 74 2d 65 70 78 20 64 66 40 ps_fix_t-epx df@
2060: 20 66 2a 2a 32 0a 09 09 66 69 78 20 67 70 73 3a f**2...fix gps:
2070: 67 70 73 5f 66 69 78 5f 74 2d 65 70 79 20 64 66 gps_fix_t-epy df
2080: 40 20 66 2a 2a 32 0a 09 09 66 2b 20 66 73 71 72 @ f**2...f+ fsqr
2090: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 t
20a0: 20 20 20 20 20 20 20 20 20 63 6f 6f 72 64 22 20 coord"
20b0: 35 20 73 66 5b 5d 21 20 3b 0a 09 5b 54 48 45 4e 5 sf[]! ;..[THEN
20c0: 5d 0a 20 20 20 20 5b 45 4c 53 45 5d 0a 09 3a 20 ]. [ELSE]..:
20d0: 63 6f 6f 72 64 21 20 28 20 2d 2d 20 29 20 3b 0a coord! ( -- ) ;.
20e0: 20 20 20 20 5b 54 48 45 4e 5d 0a 5b 54 48 45 4e [THEN].[THEN
20f0: 5d 0a 0a 3a 20 2e 63 6f 6f 72 64 73 20 28 20 61 ]..: .coords ( a
2100: 64 64 72 20 75 20 2d 2d 20 29 20 24 3e 61 6c 69 ddr u -- ) $>ali
2110: 67 6e 20 64 72 6f 70 0a 20 20 20 20 64 75 70 20 gn drop. dup
2120: 30 20 73 66 5b 5d 40 20 66 64 75 70 20 66 61 62 0 sf[]@ fdup fab
2130: 73 20 2e 64 65 67 20 66 30 3c 20 27 53 27 20 27 s .deg f0< 'S' '
2140: 4e 27 20 72 6f 74 20 73 65 6c 65 63 74 20 65 6d N' rot select em
2150: 69 74 20 73 70 61 63 65 0a 20 20 20 20 64 75 70 it space. dup
2160: 20 31 20 73 66 5b 5d 40 20 66 64 75 70 20 66 61 1 sf[]@ fdup fa
2170: 62 73 20 2e 64 65 67 20 66 30 3c 20 27 57 27 20 bs .deg f0< 'W'
2180: 27 45 27 20 72 6f 74 20 73 65 6c 65 63 74 20 65 'E' rot select e
2190: 6d 69 74 20 73 70 61 63 65 0a 20 20 20 20 64 75 mit space. du
21a0: 70 20 32 20 73 66 5b 5d 40 20 37 20 31 20 30 20 p 2 sf[]@ 7 1 0
21b0: 66 2e 72 64 70 20 2e 22 20 6d 20 22 0a 20 20 20 f.rdp ." m ".
21c0: 20 64 75 70 20 33 20 73 66 5b 5d 40 20 38 20 32 dup 3 sf[]@ 8 2
21d0: 20 30 20 66 2e 72 64 70 20 2e 22 20 6b 6d 2f 68 0 f.rdp ." km/h
21e0: 20 22 0a 20 20 20 20 64 75 70 20 34 20 73 66 5b ". dup 4 sf[
21f0: 5d 40 20 38 20 32 20 30 20 66 2e 72 64 70 20 2e ]@ 8 2 0 f.rdp .
2200: 22 20 c2 b0 20 7e 22 0a 20 20 20 20 64 75 70 20 " ° ~". dup
2210: 35 20 73 66 5b 5d 40 20 66 73 70 6c 69 74 20 30 5 sf[]@ fsplit 0
2220: 20 2e 72 20 27 2e 27 20 65 6d 69 74 20 31 30 30 .r '.' emit 100
2230: 65 20 66 2a 20 66 3e 73 20 2e 23 23 20 2e 22 20 e f* f>s .## ."
2240: 6d 22 0a 20 20 20 20 64 72 6f 70 20 3b 0a 0a 46 m". drop ;..F
2250: 6f 72 77 61 72 64 20 6d 73 67 3a 6c 61 73 74 3f orward msg:last?
2260: 0a 46 6f 72 77 61 72 64 20 6d 73 67 3a 6c 61 73 .Forward msg:las
2270: 74 0a 0a 3a 20 70 75 73 68 2d 6d 73 67 20 28 20 t..: push-msg (
2280: 61 64 64 72 20 75 20 6f 3a 70 61 72 65 6e 74 20 addr u o:parent
2290: 2d 2d 20 29 0a 20 20 20 20 75 70 40 20 72 65 63 -- ). up@ rec
22a0: 65 69 76 65 72 2d 74 61 73 6b 20 3c 3e 20 49 46 eiver-task <> IF
22b0: 0a 09 61 76 61 6c 61 6e 63 68 65 2d 6d 73 67 0a ..avalanche-msg.
22c0: 20 20 20 20 45 4c 53 45 20 77 61 69 74 2d 74 61 ELSE wait-ta
22d0: 73 6b 20 40 20 3f 64 75 70 2d 49 46 0a 09 20 20 sk @ ?dup-IF..
22e0: 20 20 3c 65 76 65 6e 74 20 3e 72 20 65 24 2c 20 <event >r e$,
22f0: 6f 20 65 6c 69 74 2c 20 6d 73 67 2d 67 72 6f 75 o elit, msg-grou
2300: 70 2d 6f 20 65 6c 69 74 2c 0a 09 20 20 20 20 3a p-o elit,.. :
2310: 3e 61 76 61 6c 61 6e 63 68 65 20 72 3e 20 65 76 >avalanche r> ev
2320: 65 6e 74 3e 0a 09 45 4c 53 45 20 20 32 64 72 6f ent>..ELSE 2dro
2330: 70 20 20 54 48 45 4e 0a 20 20 20 20 54 48 45 4e p THEN. THEN
2340: 20 3b 0a 3a 20 73 68 6f 77 2d 6d 73 67 20 28 20 ;.: show-msg (
2350: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
2360: 70 61 72 65 6e 74 20 64 75 70 20 49 46 20 20 2e parent dup IF .
2370: 77 61 69 74 2d 74 61 73 6b 20 40 20 64 75 70 20 wait-task @ dup
2380: 75 70 40 20 3c 3e 20 61 6e 64 20 20 54 48 45 4e up@ <> and THEN
2390: 0a 20 20 20 20 3f 64 75 70 2d 49 46 0a 09 3e 72 . ?dup-IF..>r
23a0: 20 72 40 20 3c 68 69 64 65 3e 20 3c 65 76 65 6e r@ <hide> <even
23b0: 74 20 24 6d 61 6b 65 20 65 6c 69 74 2c 20 6f 20 t $make elit, o
23c0: 65 6c 69 74 2c 20 6d 73 67 2d 67 72 6f 75 70 2d elit, msg-group-
23d0: 6f 20 65 6c 69 74 2c 20 3a 3e 6d 73 67 2d 6e 65 o elit, :>msg-ne
23e0: 73 74 73 69 67 0a 09 72 3e 20 65 76 65 6e 74 3e stsig..r> event>
23f0: 0a 20 20 20 20 45 4c 53 45 20 20 64 6f 2d 6d 73 . ELSE do-ms
2400: 67 2d 6e 65 73 74 73 69 67 20 20 54 48 45 4e 20 g-nestsig THEN
2410: 3b 0a 0a 3a 20 64 61 74 65 3e 69 20 28 20 64 61 ;..: date>i ( da
2420: 74 65 20 2d 2d 20 69 20 29 0a 20 20 20 20 6d 73 te -- i ). ms
2430: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c g-group-o .msg:l
2440: 6f 67 5b 5d 20 24 73 65 61 72 63 68 5b 5d 64 61 og[] $search[]da
2450: 74 65 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e te msg-group-o .
2460: 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 20 31 msg:log[] $[]# 1
2470: 2d 20 75 6d 69 6e 20 3b 0a 3a 20 64 61 74 65 3e - umin ;.: date>
2480: 69 27 20 28 20 64 61 74 65 20 2d 2d 20 69 20 29 i' ( date -- i )
2490: 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f . msg-group-o
24a0: 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 73 65 61 .msg:log[] $sea
24b0: 72 63 68 5b 5d 64 61 74 65 20 6d 73 67 2d 67 72 rch[]date msg-gr
24c0: 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d oup-o .msg:log[]
24d0: 20 24 5b 5d 23 20 75 6d 69 6e 20 3b 0a 3a 20 73 $[]# umin ;.: s
24e0: 69 67 68 61 73 68 3f 20 28 20 61 64 64 72 20 75 ighash? ( addr u
24f0: 20 2d 2d 20 66 6c 61 67 20 29 0a 20 20 20 20 6f -- flag ). o
2500: 76 65 72 20 6c 65 2d 36 34 40 20 64 61 74 65 3e ver le-64@ date>
2510: 69 0a 20 20 20 20 64 75 70 20 30 3c 20 49 46 20 i. dup 0< IF
2520: 20 64 72 6f 70 20 32 64 72 6f 70 20 20 66 61 6c drop 2drop fal
2530: 73 65 20 20 45 58 49 54 20 20 54 48 45 4e 20 20 se EXIT THEN
2540: 3e 72 0a 20 20 20 20 6f 76 65 72 20 6c 65 2d 36 >r. over le-6
2550: 34 40 20 36 34 23 31 20 36 34 2b 20 64 61 74 65 4@ 64#1 64+ date
2560: 3e 69 27 20 3e 72 20 5b 20 31 20 36 34 73 20 5d >i' >r [ 1 64s ]
2570: 4c 20 2f 73 74 72 69 6e 67 0a 20 20 20 20 72 3e L /string. r>
2580: 20 72 3e 20 55 2b 44 4f 0a 09 63 3a 30 6b 65 79 r> U+DO..c:0key
2590: 20 49 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e I msg-group-o .
25a0: 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 40 20 73 msg:log[] $[]@ s
25b0: 69 67 6f 6e 6c 79 40 20 3e 68 61 73 68 0a 09 32 igonly@ >hash..2
25c0: 64 75 70 20 68 61 73 68 74 6d 70 20 6f 76 65 72 dup hashtmp over
25d0: 20 73 74 72 3d 20 49 46 20 20 32 64 72 6f 70 20 str= IF 2drop
25e0: 74 72 75 65 20 20 55 4e 4c 4f 4f 50 20 20 20 45 true UNLOOP E
25f0: 58 49 54 0a 09 45 4c 53 45 20 20 28 20 32 64 75 XIT..ELSE ( 2du
2600: 70 20 38 35 74 79 70 65 20 2e 22 20 20 3c 3e 20 p 85type ." <>
2610: 22 20 68 61 73 68 74 6d 70 20 6f 76 65 72 20 38 " hashtmp over 8
2620: 35 74 79 70 65 20 29 20 20 54 48 45 4e 0a 20 20 5type ) THEN.
2630: 20 20 4c 4f 4f 50 0a 20 20 20 20 32 64 72 6f 70 LOOP. 2drop
2640: 20 66 61 6c 73 65 20 3b 0a 0a 3a 20 6d 73 67 2d false ;..: msg-
2650: 6b 65 79 21 20 28 20 61 64 64 72 20 75 20 2d 2d key! ( addr u --
2660: 20 29 0a 20 20 20 20 30 20 6d 73 67 2d 67 72 6f ). 0 msg-gro
2670: 75 70 2d 6f 20 2e 6d 73 67 3a 6b 65 79 73 5b 5d up-o .msg:keys[]
2680: 20 5b 3a 20 72 6f 74 20 3e 72 20 32 6f 76 65 72 [: rot >r 2over
2690: 20 73 74 72 3d 20 72 3e 20 6f 72 20 3b 5d 20 24 str= r> or ;] $
26a0: 5b 5d 6d 61 70 0a 20 20 20 20 49 46 20 20 32 64 []map. IF 2d
26b0: 72 6f 70 20 20 45 4c 53 45 20 20 5c 20 2e 22 20 rop ELSE \ ."
26c0: 6d 73 67 2d 6b 65 79 2b 20 22 20 32 64 75 70 20 msg-key+ " 2dup
26d0: 38 35 74 79 70 65 20 66 6f 72 74 68 3a 63 72 0a 85type forth:cr.
26e0: 09 24 6d 61 6b 65 20 6d 73 67 2d 67 72 6f 75 70 .$make msg-group
26f0: 2d 6f 20 2e 6d 73 67 3a 6b 65 79 73 5b 5d 20 3e -o .msg:keys[] >
2700: 62 61 63 6b 20 20 54 48 45 4e 20 3b 0a 0a 5c 20 back THEN ;..\
2710: 6d 65 73 73 61 67 65 20 63 6f 6d 6d 61 6e 64 73 message commands
2720: 0a 0a 73 63 6f 70 65 7b 20 6e 65 74 32 6f 2d 62 ..scope{ net2o-b
2730: 61 73 65 0a 0a 5c 67 20 0a 5c 67 20 23 23 23 20 ase..\g .\g ###
2740: 6d 65 73 73 61 67 65 20 63 6f 6d 6d 61 6e 64 73 message commands
2750: 20 23 23 23 0a 5c 67 20 0a 0a 72 65 70 6c 79 2d ###.\g ..reply-
2760: 74 61 62 6c 65 20 24 40 20 69 6e 68 65 72 69 74 table $@ inherit
2770: 2d 74 61 62 6c 65 20 6d 73 67 2d 74 61 62 6c 65 -table msg-table
2780: 0a 0a 24 32 30 20 6e 65 74 32 6f 3a 20 6d 73 67 ..$20 net2o: msg
2790: 2d 73 74 61 72 74 20 28 20 24 3a 70 6b 73 69 67 -start ( $:pksig
27a0: 20 2d 2d 20 29 20 5c 67 20 73 74 61 72 74 20 6d -- ) \g start m
27b0: 65 73 73 61 67 65 0a 20 20 20 20 31 20 21 21 3e essage. 1 !!>
27c0: 6f 72 64 65 72 3f 20 24 3e 20 6d 73 67 3a 73 74 order? $> msg:st
27d0: 61 72 74 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d 73 art ;.+net2o: ms
27e0: 67 2d 74 61 67 20 28 20 24 3a 74 61 67 20 2d 2d g-tag ( $:tag --
27f0: 20 29 20 5c 67 20 74 61 67 67 69 6e 67 20 28 63 ) \g tagging (c
2800: 61 6e 20 62 65 20 61 6e 79 77 68 65 72 65 29 0a an be anywhere).
2810: 20 20 20 20 24 3e 20 6d 73 67 3a 74 61 67 20 3b $> msg:tag ;
2820: 0a 2b 6e 65 74 32 6f 3a 20 6d 73 67 2d 69 64 20 .+net2o: msg-id
2830: 28 20 24 3a 69 64 20 2d 2d 20 29 20 5c 67 20 61 ( $:id -- ) \g a
2840: 20 68 61 73 68 20 69 64 0a 20 20 20 20 32 20 21 hash id. 2 !
2850: 21 3e 3d 6f 72 64 65 72 3f 20 24 3e 20 6d 73 67 !>=order? $> msg
2860: 3a 69 64 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d 73 :id ;.+net2o: ms
2870: 67 2d 63 68 61 69 6e 20 28 20 24 3a 64 61 74 65 g-chain ( $:date
2880: 73 2c 73 69 67 68 61 73 68 20 2d 2d 20 29 20 5c s,sighash -- ) \
2890: 67 20 63 68 61 69 6e 65 64 20 74 6f 20 6d 65 73 g chained to mes
28a0: 73 61 67 65 5b 73 5d 0a 20 20 20 20 28 20 24 31 sage[s]. ( $1
28b0: 30 20 21 21 3e 3d 6f 72 64 65 72 3f 20 29 20 24 0 !!>=order? ) $
28c0: 3e 20 6d 73 67 3a 63 68 61 69 6e 20 3b 0a 2b 6e > msg:chain ;.+n
28d0: 65 74 32 6f 3a 20 6d 73 67 2d 73 69 67 6e 61 6c et2o: msg-signal
28e0: 20 28 20 24 3a 70 75 62 6b 65 79 20 2d 2d 20 29 ( $:pubkey -- )
28f0: 20 5c 67 20 73 69 67 6e 61 6c 20 6d 65 73 73 61 \g signal messa
2900: 67 65 20 74 6f 20 6f 6e 65 20 70 65 72 73 6f 6e ge to one person
2910: 0a 20 20 20 20 24 3e 20 6d 73 67 3a 73 69 67 6e . $> msg:sign
2920: 61 6c 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d 73 67 al ;.+net2o: msg
2930: 2d 72 65 20 28 20 24 3a 68 61 73 68 20 29 20 5c -re ( $:hash ) \
2940: 67 20 72 65 6c 61 74 65 20 74 6f 20 73 6f 6d 65 g relate to some
2950: 20 6f 62 6a 65 63 74 0a 20 20 20 20 34 20 21 21 object. 4 !!
2960: 3e 3d 6f 72 64 65 72 3f 20 24 3e 20 6d 73 67 3a >=order? $> msg:
2970: 72 65 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d 73 67 re ;.+net2o: msg
2980: 2d 74 65 78 74 20 28 20 24 3a 6d 73 67 20 2d 2d -text ( $:msg --
2990: 20 29 20 5c 67 20 73 70 65 63 69 66 79 20 6d 65 ) \g specify me
29a0: 73 73 61 67 65 20 73 74 72 69 6e 67 0a 20 20 20 ssage string.
29b0: 20 38 20 21 21 3e 3d 6f 72 64 65 72 3f 20 24 3e 8 !!>=order? $>
29c0: 20 6d 73 67 3a 74 65 78 74 20 3b 0a 2b 6e 65 74 msg:text ;.+net
29d0: 32 6f 3a 20 6d 73 67 2d 6f 62 6a 65 63 74 20 28 2o: msg-object (
29e0: 20 24 3a 6f 62 6a 65 63 74 20 74 79 70 65 20 2d $:object type -
29f0: 2d 20 29 20 5c 67 20 73 70 65 63 69 66 79 20 61 - ) \g specify a
2a00: 6e 20 6f 62 6a 65 63 74 2c 20 65 2e 67 2e 20 61 n object, e.g. a
2a10: 6e 20 69 6d 61 67 65 0a 20 20 20 20 38 20 21 21 n image. 8 !!
2a20: 3e 3d 6f 72 64 65 72 3f 20 36 34 3e 6e 20 24 3e >=order? 64>n $>
2a30: 20 72 6f 74 20 6d 73 67 3a 6f 62 6a 65 63 74 20 rot msg:object
2a40: 3b 0a 2b 6e 65 74 32 6f 3a 20 6d 73 67 2d 61 63 ;.+net2o: msg-ac
2a50: 74 69 6f 6e 20 28 20 24 3a 6d 73 67 20 2d 2d 20 tion ( $:msg --
2a60: 29 20 5c 67 20 73 70 65 63 69 66 79 20 61 63 74 ) \g specify act
2a70: 69 6f 6e 20 73 74 72 69 6e 67 0a 20 20 20 20 38 ion string. 8
2a80: 20 21 21 3e 3d 6f 72 64 65 72 3f 20 24 3e 20 6d !!>=order? $> m
2a90: 73 67 3a 61 63 74 69 6f 6e 20 3b 0a 2b 6e 65 74 sg:action ;.+net
2aa0: 32 6f 3a 20 6d 73 67 2d 70 61 79 6d 65 6e 74 20 2o: msg-payment
2ab0: 28 20 24 3a 63 6f 6e 74 72 61 63 74 20 2d 2d 20 ( $:contract --
2ac0: 29 20 5c 67 20 70 61 79 6d 65 6e 74 20 74 72 61 ) \g payment tra
2ad0: 6e 73 61 63 74 69 6f 6e 0a 20 20 20 20 38 20 21 nsaction. 8 !
2ae0: 21 3e 3d 6f 72 64 65 72 3f 20 24 3e 20 6d 73 67 !>=order? $> msg
2af0: 3a 70 61 79 6d 65 6e 74 20 3b 0a 2b 6e 65 74 32 :payment ;.+net2
2b00: 6f 3a 20 6d 73 67 2d 6f 74 72 69 66 79 20 28 20 o: msg-otrify (
2b10: 24 3a 64 61 74 65 2b 73 69 67 20 24 3a 6e 65 77 $:date+sig $:new
2b20: 64 61 74 65 2b 73 69 67 20 2d 2d 20 29 20 5c 67 date+sig -- ) \g
2b30: 20 74 75 72 6e 20 61 20 70 61 73 74 20 6d 65 73 turn a past mes
2b40: 73 61 67 65 20 69 6e 74 6f 20 4f 54 52 0a 20 20 sage into OTR.
2b50: 20 20 24 3e 20 24 3e 20 6d 73 67 3a 6f 74 72 69 $> $> msg:otri
2b60: 66 79 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d 73 67 fy ;.+net2o: msg
2b70: 2d 63 6f 6f 72 64 20 28 20 24 3a 67 70 73 20 2d -coord ( $:gps -
2b80: 2d 20 29 20 5c 67 20 47 50 53 20 63 6f 6f 72 64 - ) \g GPS coord
2b90: 69 6e 61 74 65 73 0a 20 20 20 20 38 20 21 21 3e inates. 8 !!>
2ba0: 3d 6f 72 64 65 72 3f 20 24 3e 20 6d 73 67 3a 63 =order? $> msg:c
2bb0: 6f 6f 72 64 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d oord ;.+net2o: m
2bc0: 73 67 2d 75 72 6c 20 28 20 24 3a 75 72 6c 20 2d sg-url ( $:url -
2bd0: 2d 20 29 20 5c 67 20 73 70 65 63 69 66 79 20 6d - ) \g specify m
2be0: 65 73 73 61 67 65 20 55 52 4c 0a 20 20 20 20 24 essage URL. $
2bf0: 3e 20 6d 73 67 3a 75 72 6c 20 3b 0a 2b 6e 65 74 > msg:url ;.+net
2c00: 32 6f 3a 20 6d 73 67 2d 6c 69 6b 65 20 28 20 78 2o: msg-like ( x
2c10: 63 68 61 72 20 2d 2d 20 29 20 5c 67 20 61 64 64 char -- ) \g add
2c20: 20 61 20 6c 69 6b 65 0a 20 20 20 20 36 34 3e 6e a like. 64>n
2c30: 20 6d 73 67 3a 6c 69 6b 65 20 3b 0a 2b 6e 65 74 msg:like ;.+net
2c40: 32 6f 3a 20 6d 73 67 2d 6c 6f 63 6b 20 28 20 24 2o: msg-lock ( $
2c50: 3a 6b 65 79 20 2d 2d 20 29 20 5c 67 20 6c 6f 63 :key -- ) \g loc
2c60: 6b 20 64 6f 77 6e 20 63 6f 6d 6d 75 6e 63 69 61 k down communcia
2c70: 74 69 6f 6e 0a 20 20 20 20 24 3e 20 6d 73 67 3a tion. $> msg:
2c80: 6c 6f 63 6b 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d lock ;.+net2o: m
2c90: 73 67 2d 75 6e 6c 6f 63 6b 20 28 20 2d 2d 20 29 sg-unlock ( -- )
2ca0: 20 5c 67 20 75 6e 6c 6f 63 6b 20 63 6f 6d 6d 75 \g unlock commu
2cb0: 6e 69 63 61 74 69 6f 6e 0a 20 20 20 20 6d 73 67 nication. msg
2cc0: 3a 75 6e 6c 6f 63 6b 20 3b 0a 2b 6e 65 74 32 6f :unlock ;.+net2o
2cd0: 3a 20 6d 73 67 2d 70 65 72 6d 73 20 28 20 24 3a : msg-perms ( $:
2ce0: 70 6b 20 70 65 72 6d 20 2d 2d 20 29 20 5c 67 20 pk perm -- ) \g
2cf0: 70 65 72 6d 69 73 73 69 6f 6e 73 0a 20 20 20 20 permissions.
2d00: 24 3e 20 6d 73 67 3a 70 65 72 6d 73 20 3b 0a 7d $> msg:perms ;.}
2d10: 73 63 6f 70 65 0a 0a 6d 73 67 2d 74 61 62 6c 65 scope..msg-table
2d20: 20 24 73 61 76 65 0a 0a 27 20 63 6f 6e 74 65 78 $save..' contex
2d30: 74 2d 74 61 62 6c 65 20 69 73 20 67 65 6e 2d 74 t-table is gen-t
2d40: 61 62 6c 65 0a 0a 5c 20 43 6f 64 65 20 66 6f 72 able..\ Code for
2d50: 20 64 69 73 70 6c 61 79 69 6e 67 20 6d 65 73 73 displaying mess
2d60: 61 67 65 73 0a 0a 44 65 66 65 72 20 2e 6c 6f 67 ages..Defer .log
2d70: 2d 6e 75 6d 0a 44 65 66 65 72 20 2e 6c 6f 67 2d -num.Defer .log-
2d80: 64 61 74 65 0a 44 65 66 65 72 20 2e 6c 6f 67 2d date.Defer .log-
2d90: 65 6e 64 0a 0a 3a 20 2e 6f 74 72 2d 69 6e 66 6f end..: .otr-info
2da0: 20 28 20 2d 2d 20 29 0a 20 20 20 20 3c 69 6e 66 ( -- ). <inf
2db0: 6f 3e 20 2e 22 20 5b 6f 74 72 5d 20 22 20 3c 64 o> ." [otr] " <d
2dc0: 65 66 61 75 6c 74 3e 20 22 5b 6f 74 72 5d 20 22 efault> "[otr] "
2dd0: 20 6e 6f 74 69 66 79 2b 20 6e 6f 74 69 66 79 2d notify+ notify-
2de0: 6f 74 72 3f 20 6f 6e 20 3b 0a 3a 20 2e 6f 74 72 otr? on ;.: .otr
2df0: 2d 65 72 72 20 28 20 2d 2d 20 29 0a 20 20 20 20 -err ( -- ).
2e00: 3c 65 72 72 3e 20 2e 22 20 5b 65 78 70 5d 20 22 <err> ." [exp] "
2e10: 20 3c 64 65 66 61 75 6c 74 3e 20 31 20 6e 6f 74 <default> 1 not
2e20: 69 66 79 2d 6f 74 72 3f 20 21 20 3b 0a 3a 20 2e ify-otr? ! ;.: .
2e30: 6f 74 72 20 28 20 74 69 63 6b 20 2d 2d 20 29 0a otr ( tick -- ).
2e40: 20 20 20 20 36 34 64 75 70 20 36 34 23 2d 31 20 64dup 64#-1
2e50: 36 34 3d 20 49 46 20 20 36 34 64 72 6f 70 20 20 64= IF 64drop
2e60: 6e 6f 74 69 66 79 2d 6f 74 72 3f 20 6f 66 66 20 notify-otr? off
2e70: 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 EXIT THEN.
2e80: 74 69 63 6b 73 20 36 34 2d 20 36 34 64 75 70 20 ticks 64- 64dup
2e90: 66 75 7a 7a 65 64 74 69 6d 65 23 20 36 34 6e 65 fuzzedtime# 64ne
2ea0: 67 61 74 65 20 36 34 3c 20 49 46 20 20 36 34 64 gate 64< IF 64d
2eb0: 72 6f 70 20 2e 6f 74 72 2d 65 72 72 20 20 45 58 rop .otr-err EX
2ec0: 49 54 20 20 54 48 45 4e 0a 20 20 20 20 6f 74 72 IT THEN. otr
2ed0: 73 69 67 2d 64 65 6c 74 61 23 20 66 75 7a 7a 65 sig-delta# fuzze
2ee0: 64 74 69 6d 65 23 20 36 34 2b 20 36 34 3c 20 49 dtime# 64+ 64< I
2ef0: 46 20 20 2e 6f 74 72 2d 69 6e 66 6f 20 20 54 48 F .otr-info TH
2f00: 45 4e 20 3b 0a 3a 20 2e 67 72 6f 75 70 20 28 20 EN ;.: .group (
2f10: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
2f20: 32 64 75 70 20 70 72 69 6e 74 61 62 6c 65 3f 20 2dup printable?
2f30: 49 46 20 20 66 6f 72 74 68 3a 74 79 70 65 20 20 IF forth:type
2f40: 45 4c 53 45 20 20 2e 22 20 40 22 20 2e 6b 65 79 ELSE ." @" .key
2f50: 2d 69 64 20 20 54 48 45 4e 20 3b 0a 0a 73 63 6f -id THEN ;..sco
2f60: 70 65 3a 20 6c 6f 67 73 74 79 6c 65 73 0a 3a 20 pe: logstyles.:
2f70: 2b 6e 75 6d 20 5b 3a 20 27 23 27 20 65 6d 69 74 +num [: '#' emit
2f80: 20 6c 6f 67 23 20 75 2e 20 3b 5d 20 69 73 20 2e log# u. ;] is .
2f90: 6c 6f 67 2d 6e 75 6d 20 3b 0a 3a 20 2d 6e 75 6d log-num ;.: -num
2fa0: 20 5b 27 5d 20 6e 6f 6f 70 20 69 73 20 2e 6c 6f ['] noop is .lo
2fb0: 67 2d 6e 75 6d 20 3b 0a 3a 20 2b 64 61 74 65 20 g-num ;.: +date
2fc0: 5b 3a 20 2e 74 69 63 6b 73 20 73 70 61 63 65 20 [: .ticks space
2fd0: 3b 5d 20 69 73 20 2e 6c 6f 67 2d 64 61 74 65 20 ;] is .log-date
2fe0: 3b 0a 3a 20 2d 64 61 74 65 20 5b 27 5d 20 36 34 ;.: -date ['] 64
2ff0: 64 72 6f 70 20 69 73 20 2e 6c 6f 67 2d 64 61 74 drop is .log-dat
3000: 65 20 3b 0a 3a 20 2b 65 6e 64 20 5b 3a 20 36 34 e ;.: +end [: 64
3010: 64 75 70 20 2e 74 69 63 6b 73 20 73 70 61 63 65 dup .ticks space
3020: 20 2e 6f 74 72 20 3b 5d 20 69 73 20 2e 6c 6f 67 .otr ;] is .log
3030: 2d 65 6e 64 20 3b 0a 3a 20 2d 65 6e 64 20 5b 27 -end ;.: -end ['
3040: 5d 20 2e 6f 74 72 20 69 73 20 2e 6c 6f 67 2d 65 ] .otr is .log-e
3050: 6e 64 20 3b 0a 0a 2b 64 61 74 65 20 2d 6e 75 6d nd ;..+date -num
3060: 20 2d 65 6e 64 0a 7d 73 63 6f 70 65 0a 0a 3a 6e -end.}scope..:n
3070: 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d oname ( addr u -
3080: 2d 20 29 0a 20 20 20 20 6c 61 73 74 23 20 3e 72 - ). last# >r
3090: 20 20 32 64 75 70 20 6b 65 79 7c 20 74 6f 20 6d 2dup key| to m
30a0: 73 67 3a 69 64 24 0a 20 20 20 20 5b 3a 20 2e 73 sg:id$. [: .s
30b0: 69 6d 70 6c 65 2d 69 64 20 2e 22 20 3a 20 22 20 imple-id ." : "
30c0: 3b 5d 20 24 74 6d 70 20 6e 6f 74 69 66 79 2d 6e ;] $tmp notify-n
30d0: 69 63 6b 21 0a 20 20 20 20 72 3e 20 74 6f 20 6c ick!. r> to l
30e0: 61 73 74 23 20 3b 20 6d 73 67 2d 6e 6f 74 69 66 ast# ; msg-notif
30f0: 79 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 73 y-class is msg:s
3100: 74 61 72 74 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 tart.:noname ( a
3110: 64 64 72 20 75 20 2d 2d 20 29 20 22 23 22 20 6e ddr u -- ) "#" n
3120: 6f 74 69 66 79 2b 20 24 75 74 66 38 3e 20 6e 6f otify+ $utf8> no
3130: 74 69 66 79 2b 0a 3b 20 6d 73 67 2d 6e 6f 74 69 tify+.; msg-noti
3140: 66 79 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a fy-class is msg:
3150: 74 61 67 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 tag.:noname ( ad
3160: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 32 64 dr u -- ). 2d
3170: 75 70 20 5b 3a 20 2e 22 20 40 22 20 2e 73 69 6d up [: ." @" .sim
3180: 70 6c 65 2d 69 64 20 3b 5d 20 24 74 6d 70 20 6e ple-id ;] $tmp n
3190: 6f 74 69 66 79 2b 20 3b 20 6d 73 67 2d 6e 6f 74 otify+ ; msg-not
31a0: 69 66 79 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 ify-class is msg
31b0: 3a 73 69 67 6e 61 6c 0a 3a 6e 6f 6e 61 6d 65 20 :signal.:noname
31c0: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 24 75 ( addr u -- ) $u
31d0: 74 66 38 3e 20 6e 6f 74 69 66 79 2b 20 3b 20 6d tf8> notify+ ; m
31e0: 73 67 2d 6e 6f 74 69 66 79 2d 63 6c 61 73 73 20 sg-notify-class
31f0: 69 73 20 6d 73 67 3a 74 65 78 74 0a 3a 6e 6f 6e is msg:text.:non
3200: 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 ame ( addr u --
3210: 29 20 24 75 74 66 38 3e 20 6e 6f 74 69 66 79 2b ) $utf8> notify+
3220: 20 3b 20 6d 73 67 2d 6e 6f 74 69 66 79 2d 63 6c ; msg-notify-cl
3230: 61 73 73 20 69 73 20 6d 73 67 3a 75 72 6c 0a 3a ass is msg:url.:
3240: 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 noname ( addr u
3250: 2d 2d 20 29 20 24 75 74 66 38 3e 20 6e 6f 74 69 -- ) $utf8> noti
3260: 66 79 2b 20 3b 20 6d 73 67 2d 6e 6f 74 69 66 79 fy+ ; msg-notify
3270: 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 61 63 -class is msg:ac
3280: 74 69 6f 6e 0a 27 20 64 72 6f 70 20 20 6d 73 67 tion.' drop msg
3290: 2d 6e 6f 74 69 66 79 2d 63 6c 61 73 73 20 69 73 -notify-class is
32a0: 20 6d 73 67 3a 6c 69 6b 65 0a 27 20 32 64 72 6f msg:like.' 2dro
32b0: 70 20 20 6d 73 67 2d 6e 6f 74 69 66 79 2d 63 6c p msg-notify-cl
32c0: 61 73 73 20 69 73 20 6d 73 67 3a 6c 6f 63 6b 0a ass is msg:lock.
32d0: 27 20 6e 6f 6f 70 20 20 6d 73 67 2d 6e 6f 74 69 ' noop msg-noti
32e0: 66 79 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a fy-class is msg:
32f0: 75 6e 6c 6f 63 6b 0a 3a 6e 6f 6e 61 6d 65 20 32 unlock.:noname 2
3300: 64 72 6f 70 20 36 34 64 72 6f 70 20 3b 20 6d 73 drop 64drop ; ms
3310: 67 2d 6e 6f 74 69 66 79 2d 63 6c 61 73 73 20 69 g-notify-class i
3320: 73 20 6d 73 67 3a 70 65 72 6d 73 0a 27 20 64 72 s msg:perms.' dr
3330: 6f 70 20 20 6d 73 67 2d 6e 6f 74 69 66 79 2d 63 op msg-notify-c
3340: 6c 61 73 73 20 69 73 20 6d 73 67 3a 61 77 61 79 lass is msg:away
3350: 0a 27 20 32 64 72 6f 70 20 6d 73 67 2d 6e 6f 74 .' 2drop msg-not
3360: 69 66 79 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 ify-class is msg
3370: 3a 63 6f 6f 72 64 0a 3a 6e 6f 6e 61 6d 65 20 32 :coord.:noname 2
3380: 64 72 6f 70 20 32 64 72 6f 70 20 3b 20 6d 73 67 drop 2drop ; msg
3390: 2d 6e 6f 74 69 66 79 2d 63 6c 61 73 73 20 69 73 -notify-class is
33a0: 20 6d 73 67 3a 6f 74 72 69 66 79 0a 3a 6e 6f 6e msg:otrify.:non
33b0: 61 6d 65 20 28 20 2d 2d 20 29 20 6d 73 67 2d 6e ame ( -- ) msg-n
33c0: 6f 74 69 66 79 20 3b 20 6d 73 67 2d 6e 6f 74 69 otify ; msg-noti
33d0: 66 79 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a fy-class is msg:
33e0: 65 6e 64 0a 3a 6e 6f 6e 61 6d 65 20 28 20 78 63 end.:noname ( xc
33f0: 68 61 72 20 2d 2d 20 29 20 5b 27 5d 20 78 65 6d har -- ) ['] xem
3400: 69 74 20 24 74 6d 70 20 6e 6f 74 69 66 79 2b 20 it $tmp notify+
3410: 3b 20 6d 73 67 2d 6e 6f 74 69 66 79 2d 63 6c 61 ; msg-notify-cla
3420: 73 73 20 69 73 20 6d 73 67 3a 6c 69 6b 65 0a 0a ss is msg:like..
3430: 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 :noname ( addr u
3440: 20 2d 2d 20 29 0a 20 20 20 20 6c 61 73 74 23 20 -- ). last#
3450: 3e 72 20 20 32 64 75 70 20 6b 65 79 7c 20 74 6f >r 2dup key| to
3460: 20 6d 73 67 3a 69 64 24 0a 20 20 20 20 2e 6c 6f msg:id$. .lo
3470: 67 2d 6e 75 6d 0a 20 20 20 20 32 64 75 70 20 73 g-num. 2dup s
3480: 74 61 72 74 64 61 74 65 40 20 2e 6c 6f 67 2d 64 tartdate@ .log-d
3490: 61 74 65 0a 20 20 20 20 32 64 75 70 20 65 6e 64 ate. 2dup end
34a0: 64 61 74 65 40 20 2e 6c 6f 67 2d 65 6e 64 0a 20 date@ .log-end.
34b0: 20 20 20 2e 6b 65 79 2d 69 64 20 2e 22 20 3a 20 .key-id ." :
34c0: 22 20 0a 20 20 20 20 72 3e 20 74 6f 20 6c 61 73 " . r> to las
34d0: 74 23 20 3b 20 6d 73 67 2d 63 6c 61 73 73 20 69 t# ; msg-class i
34e0: 73 20 6d 73 67 3a 73 74 61 72 74 0a 3a 6e 6f 6e s msg:start.:non
34f0: 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 ame ( addr u --
3500: 29 20 24 75 74 66 38 3e 0a 20 20 20 20 3c 77 61 ) $utf8>. <wa
3510: 72 6e 3e 20 27 23 27 20 66 6f 72 74 68 3a 65 6d rn> '#' forth:em
3520: 69 74 20 2e 67 72 6f 75 70 20 3c 64 65 66 61 75 it .group <defau
3530: 6c 74 3e 20 3b 20 6d 73 67 2d 63 6c 61 73 73 20 lt> ; msg-class
3540: 69 73 20 6d 73 67 3a 74 61 67 0a 3a 6e 6f 6e 61 is msg:tag.:nona
3550: 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 me ( addr u -- )
3560: 20 6c 61 73 74 23 20 3e 72 0a 20 20 20 20 6b 65 last# >r. ke
3570: 79 7c 20 32 64 75 70 20 30 20 2e 70 6b 40 20 6b y| 2dup 0 .pk@ k
3580: 65 79 7c 20 73 74 72 3d 0a 20 20 20 20 49 46 20 ey| str=. IF
3590: 20 20 3c 65 72 72 3e 20 20 54 48 45 4e 20 2e 22 <err> THEN ."
35a0: 20 40 22 20 2e 6b 65 79 2d 69 64 3f 20 3c 64 65 @" .key-id? <de
35b0: 66 61 75 6c 74 3e 0a 20 20 20 20 72 3e 20 74 6f fault>. r> to
35c0: 20 6c 61 73 74 23 20 3b 20 6d 73 67 2d 63 6c 61 last# ; msg-cla
35d0: 73 73 20 69 73 20 6d 73 67 3a 73 69 67 6e 61 6c ss is msg:signal
35e0: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 .:noname ( addr
35f0: 75 20 2d 2d 20 29 0a 20 20 20 20 6c 61 73 74 23 u -- ). last#
3600: 20 3e 72 20 6c 61 73 74 23 20 24 40 20 3e 67 72 >r last# $@ >gr
3610: 6f 75 70 0a 20 20 20 20 32 64 75 70 20 73 69 67 oup. 2dup sig
3620: 68 61 73 68 3f 20 49 46 20 20 3c 69 6e 66 6f 3e hash? IF <info>
3630: 20 20 45 4c 53 45 20 20 3c 65 72 72 3e 20 20 54 ELSE <err> T
3640: 48 45 4e 0a 20 20 20 20 2e 22 20 20 3c 22 20 6f HEN. ." <" o
3650: 76 65 72 20 6c 65 2d 36 34 40 20 2e 74 69 63 6b ver le-64@ .tick
3660: 73 0a 20 20 20 20 76 65 72 62 6f 73 65 28 20 64 s. verbose( d
3670: 75 70 20 6b 65 79 73 69 7a 65 20 2d 20 2f 73 74 up keysize - /st
3680: 72 69 6e 67 20 2e 22 20 2c 22 20 38 35 74 79 70 ring ." ," 85typ
3690: 65 20 29 65 6c 73 65 28 20 32 64 72 6f 70 20 29 e )else( 2drop )
36a0: 20 3c 64 65 66 61 75 6c 74 3e 0a 20 20 20 20 72 <default>. r
36b0: 3e 20 74 6f 20 6c 61 73 74 23 20 3b 20 6d 73 67 > to last# ; msg
36c0: 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 63 68 -class is msg:ch
36d0: 61 69 6e 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 ain.:noname ( ad
36e0: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 73 70 dr u -- ). sp
36f0: 61 63 65 20 3c 77 61 72 6e 3e 20 2e 22 20 5b 22 ace <warn> ." ["
3700: 20 38 35 74 79 70 65 20 2e 22 20 5d 2d 3e 22 20 85type ." ]->"
3710: 3c 64 65 66 61 75 6c 74 3e 20 3b 20 6d 73 67 2d <default> ; msg-
3720: 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 72 65 0a class is msg:re.
3730: 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 :noname ( addr u
3740: 20 2d 2d 20 29 0a 20 20 20 20 73 70 61 63 65 20 -- ). space
3750: 3c 77 61 72 6e 3e 20 2e 22 20 5b 22 20 38 35 74 <warn> ." [" 85t
3760: 79 70 65 20 2e 22 20 5d 3a 22 20 3c 64 65 66 61 ype ." ]:" <defa
3770: 75 6c 74 3e 20 3b 20 6d 73 67 2d 63 6c 61 73 73 ult> ; msg-class
3780: 20 69 73 20 6d 73 67 3a 69 64 0a 3a 6e 6f 6e 61 is msg:id.:nona
3790: 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 me ( addr u -- )
37a0: 20 24 75 74 66 38 3e 20 66 6f 72 74 68 3a 74 79 $utf8> forth:ty
37b0: 70 65 20 3b 20 6d 73 67 2d 63 6c 61 73 73 20 69 pe ; msg-class i
37c0: 73 20 6d 73 67 3a 74 65 78 74 0a 3a 6e 6f 6e 61 s msg:text.:nona
37d0: 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 me ( addr u -- )
37e0: 20 24 75 74 66 38 3e 0a 20 20 20 20 3c 77 61 72 $utf8>. <war
37f0: 6e 3e 20 66 6f 72 74 68 3a 74 79 70 65 20 3c 64 n> forth:type <d
3800: 65 66 61 75 6c 74 3e 20 3b 20 6d 73 67 2d 63 6c efault> ; msg-cl
3810: 61 73 73 20 69 73 20 6d 73 67 3a 75 72 6c 0a 3a ass is msg:url.:
3820: 6e 6f 6e 61 6d 65 20 28 20 78 63 68 61 72 20 2d noname ( xchar -
3830: 2d 20 29 0a 20 20 20 20 3c 69 6e 66 6f 3e 20 75 - ). <info> u
3840: 74 66 38 65 6d 69 74 20 3c 64 65 66 61 75 6c 74 tf8emit <default
3850: 3e 20 3b 20 6d 73 67 2d 63 6c 61 73 73 20 69 73 > ; msg-class is
3860: 20 6d 73 67 3a 6c 69 6b 65 0a 3a 6e 6f 6e 61 6d msg:like.:nonam
3870: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a e ( addr u -- ).
3880: 20 20 20 20 30 20 2e 76 2d 64 65 63 24 20 64 75 0 .v-dec$ du
3890: 70 20 49 46 0a 09 6d 73 67 2d 6b 65 79 21 20 20 p IF..msg-key!
38a0: 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 msg-group-o .msg
38b0: 3a 2b 6c 6f 63 6b 0a 09 3c 69 6e 66 6f 3e 20 2e :+lock..<info> .
38c0: 22 20 63 68 61 74 20 69 73 20 6c 6f 63 6b 65 64 " chat is locked
38d0: 22 20 3c 64 65 66 61 75 6c 74 3e 0a 20 20 20 20 " <default>.
38e0: 45 4c 53 45 20 20 32 64 72 6f 70 0a 09 3c 65 72 ELSE 2drop..<er
38f0: 72 3e 20 2e 22 20 6c 6f 63 6b 65 64 20 6f 75 74 r> ." locked out
3900: 20 6f 66 20 63 68 61 74 22 20 3c 64 65 66 61 75 of chat" <defau
3910: 6c 74 3e 0a 20 20 20 20 54 48 45 4e 20 3b 20 6d lt>. THEN ; m
3920: 73 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a sg-class is msg:
3930: 6c 6f 63 6b 0a 3a 6e 6f 6e 61 6d 65 20 28 20 2d lock.:noname ( -
3940: 2d 20 29 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f - ) msg-group-o
3950: 20 2e 6d 73 67 3a 2d 6c 6f 63 6b 0a 20 20 20 20 .msg:-lock.
3960: 3c 69 6e 66 6f 3e 20 2e 22 20 63 68 61 74 20 69 <info> ." chat i
3970: 73 20 66 72 65 65 20 66 6f 72 20 61 6c 6c 22 20 s free for all"
3980: 3c 64 65 66 61 75 6c 74 3e 20 3b 20 6d 73 67 2d <default> ; msg-
3990: 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 75 6e 6c class is msg:unl
39a0: 6f 63 6b 0a 27 20 64 72 6f 70 20 6d 73 67 2d 63 ock.' drop msg-c
39b0: 6c 61 73 73 20 69 73 20 6d 73 67 3a 61 77 61 79 lass is msg:away
39c0: 0a 3a 20 2e 70 65 72 6d 73 20 28 20 6e 20 2d 2d .: .perms ( n --
39d0: 20 29 0a 20 20 20 20 22 ef 94 85 ef 94 82 ef 94 ). "ď”
39e0: 81 f0 9f 91 b9 22 20 62 6f 75 6e 64 73 20 55 2b 👹" bounds U+
39f0: 44 4f 0a 09 64 75 70 20 31 20 61 6e 64 20 49 46 DO..dup 1 and IF
3a00: 20 20 49 20 78 63 40 20 78 65 6d 69 74 20 20 54 I xc@ xemit T
3a10: 48 45 4e 20 20 32 2f 0a 20 20 20 20 49 20 49 27 HEN 2/. I I'
3a20: 20 6f 76 65 72 20 2d 20 78 2d 73 69 7a 65 20 20 over - x-size
3a30: 2b 4c 4f 4f 50 20 20 64 72 6f 70 20 3b 0a 3a 6e +LOOP drop ;.:n
3a40: 6f 6e 61 6d 65 20 7b 20 36 34 5e 20 70 65 72 6d oname { 64^ perm
3a50: 20 64 3a 20 70 6b 20 2d 2d 20 7d 0a 20 20 20 20 d: pk -- }.
3a60: 70 65 72 6d 20 5b 20 31 20 36 34 73 20 5d 4c 20 perm [ 1 64s ]L
3a70: 70 6b 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e pk msg-group-o .
3a80: 6d 73 67 3a 70 65 72 6d 73 23 20 23 21 0a 20 20 msg:perms# #!.
3a90: 20 20 70 6b 20 2e 6b 65 79 2d 69 64 20 2e 22 20 pk .key-id ."
3aa0: 3a 20 22 20 70 65 72 6d 20 36 34 40 20 36 34 3e : " perm 64@ 64>
3ab0: 6e 20 2e 70 65 72 6d 73 20 73 70 61 63 65 0a 3b n .perms space.;
3ac0: 20 6d 73 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 msg-class is ms
3ad0: 67 3a 70 65 72 6d 73 0a 3a 6e 6f 6e 61 6d 65 20 g:perms.:noname
3ae0: 28 20 61 64 64 72 20 75 20 74 79 70 65 20 2d 2d ( addr u type --
3af0: 20 29 0a 20 20 20 20 73 70 61 63 65 20 3c 77 61 ). space <wa
3b00: 72 6e 3e 20 63 61 73 65 0a 09 6d 73 67 3a 69 6d rn> case..msg:im
3b10: 61 67 65 23 20 20 20 20 20 6f 66 20 20 2e 22 20 age# of ."
3b20: 69 6d 67 5b 22 20 20 20 20 20 20 38 35 74 79 70 img[" 85typ
3b30: 65 20 20 65 6e 64 6f 66 0a 09 6d 73 67 3a 74 68 e endof..msg:th
3b40: 75 6d 62 6e 61 69 6c 23 20 6f 66 20 20 2e 22 20 umbnail# of ."
3b50: 74 68 75 6d 62 5b 22 20 20 20 20 38 35 74 79 70 thumb[" 85typ
3b60: 65 20 20 65 6e 64 6f 66 0a 09 6d 73 67 3a 70 61 e endof..msg:pa
3b70: 74 63 68 23 20 20 20 20 20 6f 66 20 20 2e 22 20 tch# of ."
3b80: 70 61 74 63 68 5b 22 20 20 20 20 38 35 74 79 70 patch[" 85typ
3b90: 65 20 20 65 6e 64 6f 66 0a 09 6d 73 67 3a 73 6e e endof..msg:sn
3ba0: 61 70 73 68 6f 74 23 20 20 6f 66 20 20 2e 22 20 apshot# of ."
3bb0: 73 6e 61 70 73 68 6f 74 5b 22 20 38 35 74 79 70 snapshot[" 85typ
3bc0: 65 20 20 65 6e 64 6f 66 0a 09 6d 73 67 3a 6d 65 e endof..msg:me
3bd0: 73 73 61 67 65 23 20 20 20 6f 66 20 20 2e 22 20 ssage# of ."
3be0: 6d 65 73 73 61 67 65 5b 22 20 20 38 35 74 79 70 message[" 85typ
3bf0: 65 20 20 65 6e 64 6f 66 0a 09 64 72 6f 70 0a 09 e endof..drop..
3c00: 32 64 75 70 20 6b 65 79 73 69 7a 65 20 2f 73 74 2dup keysize /st
3c10: 72 69 6e 67 0a 09 32 64 75 70 20 70 72 69 6e 74 ring..2dup print
3c20: 61 62 6c 65 3f 20 49 46 20 20 27 5b 27 20 65 6d able? IF '[' em
3c30: 69 74 20 20 74 79 70 65 20 27 40 27 20 65 6d 69 it type '@' emi
3c40: 74 0a 09 45 4c 53 45 20 20 2e 22 20 23 5b 22 20 t..ELSE ." #["
3c50: 20 38 35 74 79 70 65 20 2e 22 20 2f 40 22 20 20 85type ." /@"
3c60: 54 48 45 4e 0a 09 6b 65 79 7c 20 2e 6b 65 79 2d THEN..key| .key-
3c70: 69 64 0a 09 30 0a 20 20 20 20 65 6e 64 63 61 73 id..0. endcas
3c80: 65 20 2e 22 20 5d 22 20 3c 64 65 66 61 75 6c 74 e ." ]" <default
3c90: 3e 20 3b 0a 6d 73 67 2d 63 6c 61 73 73 20 69 73 > ;.msg-class is
3ca0: 20 6d 73 67 3a 6f 62 6a 65 63 74 0a 3a 6e 6f 6e msg:object.:non
3cb0: 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 ame ( addr u --
3cc0: 29 20 24 75 74 66 38 3e 0a 20 20 20 20 3c 77 61 ) $utf8>. <wa
3cd0: 72 6e 3e 20 66 6f 72 74 68 3a 74 79 70 65 20 3c rn> forth:type <
3ce0: 64 65 66 61 75 6c 74 3e 20 3b 20 6d 73 67 2d 63 default> ; msg-c
3cf0: 6c 61 73 73 20 69 73 20 6d 73 67 3a 61 63 74 69 lass is msg:acti
3d00: 6f 6e 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 on.:noname ( add
3d10: 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 3c 77 61 r u -- ). <wa
3d20: 72 6e 3e 20 2e 22 20 20 47 50 53 3a 20 22 20 2e rn> ." GPS: " .
3d30: 63 6f 6f 72 64 73 20 3c 64 65 66 61 75 6c 74 3e coords <default>
3d40: 20 3b 20 6d 73 67 2d 63 6c 61 73 73 20 69 73 20 ; msg-class is
3d50: 6d 73 67 3a 63 6f 6f 72 64 0a 0a 3a 20 77 61 69 msg:coord..: wai
3d60: 74 2d 32 73 2d 6b 65 79 20 28 20 2d 2d 20 29 0a t-2s-key ( -- ).
3d70: 20 20 20 20 6e 74 69 6d 65 20 35 30 20 30 20 44 ntime 50 0 D
3d80: 4f 20 20 6b 65 79 3f 20 3f 4c 45 41 56 45 0a 20 O key? ?LEAVE.
3d90: 20 20 20 32 64 75 70 20 69 20 23 34 30 30 30 30 2dup i #40000
3da0: 30 30 30 20 75 6d 2a 20 64 2b 20 64 65 61 64 6c 000 um* d+ deadl
3db0: 69 6e 65 20 20 4c 4f 4f 50 20 20 32 64 72 6f 70 ine LOOP 2drop
3dc0: 20 3b 0a 3a 20 78 63 6c 65 61 72 20 28 20 61 64 ;.: xclear ( ad
3dd0: 64 72 20 75 20 2d 2d 20 29 20 78 2d 77 69 64 74 dr u -- ) x-widt
3de0: 68 20 31 2b 20 78 2d 65 72 61 73 65 20 3b 0a 0a h 1+ x-erase ;..
3df0: 3a 6e 6f 6e 61 6d 65 20 28 20 2d 2d 20 29 0a 20 :noname ( -- ).
3e00: 20 20 20 3c 69 6e 66 6f 3e 0a 20 20 20 20 5b 3a <info>. [:
3e10: 20 2e 22 20 6e 6f 62 6f 64 79 27 73 20 6f 6e 6c ." nobody's onl
3e20: 69 6e 65 22 20 6d 73 67 2d 67 72 6f 75 70 2d 6f ine" msg-group-o
3e30: 20 2e 6d 73 67 3a 3f 6f 74 72 20 30 3d 20 49 46 .msg:?otr 0= IF
3e40: 20 2e 22 20 2c 20 73 61 76 69 6e 67 20 61 77 61 ." , saving awa
3e50: 79 22 20 20 54 48 45 4e 20 3b 5d 20 24 74 6d 70 y" THEN ;] $tmp
3e60: 0a 20 20 20 20 32 64 75 70 20 74 79 70 65 20 3c . 2dup type <
3e70: 64 65 66 61 75 6c 74 3e 0a 20 20 20 20 77 61 69 default>. wai
3e80: 74 2d 32 73 2d 6b 65 79 20 78 63 6c 65 61 72 20 t-2s-key xclear
3e90: 3b 20 6d 73 67 2d 63 6c 61 73 73 20 69 73 20 6d ; msg-class is m
3ea0: 73 67 3a 2e 6e 6f 62 6f 64 79 0a 0a 5c 20 65 6e sg:.nobody..\ en
3eb0: 63 72 79 70 74 2b 73 69 67 6e 0a 5c 20 66 65 61 crypt+sign.\ fea
3ec0: 74 75 72 65 73 3a 20 73 69 67 6e 61 74 75 72 65 tures: signature
3ed0: 20 76 65 72 69 66 69 63 61 74 69 6f 6e 20 6f 6e verification on
3ee0: 6c 79 20 77 68 65 6e 20 6b 65 79 20 69 73 20 6b ly when key is k
3ef0: 6e 6f 77 6e 0a 5c 20 20 20 20 20 20 20 20 20 20 nown.\
3f00: 20 69 64 65 6e 74 69 74 79 20 6f 6e 6c 79 20 72 identity only r
3f10: 65 76 65 61 6c 65 64 20 77 68 65 6e 20 63 6f 72 evealed when cor
3f20: 72 65 63 74 6c 79 20 64 65 63 72 79 70 74 65 64 rectly decrypted
3f30: 0a 0a 3a 20 6d 73 67 2d 64 65 63 2d 73 69 67 3f ..: msg-dec-sig?
3f40: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 ( addr u -- add
3f50: 72 27 20 75 27 20 66 6c 61 67 20 29 0a 20 20 20 r' u' flag ).
3f60: 20 73 69 67 70 6b 73 69 7a 65 23 20 2d 20 32 64 sigpksize# - 2d
3f70: 75 70 20 2b 20 7b 20 70 6b 73 69 67 20 7d 0a 20 up + { pksig }.
3f80: 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e msg-group-o .
3f90: 6d 73 67 3a 6b 65 79 73 5b 5d 20 24 40 20 62 6f msg:keys[] $@ bo
3fa0: 75 6e 64 73 20 55 2b 44 4f 0a 09 49 20 24 40 20 unds U+DO..I $@
3fb0: 32 6f 76 65 72 20 70 6b 73 69 67 20 64 65 63 72 2over pksig decr
3fc0: 79 70 74 2d 73 69 67 3f 0a 09 64 75 70 20 2d 35 ypt-sig?..dup -5
3fd0: 20 3c 3e 20 49 46 0a 09 20 20 20 20 3e 72 20 32 <> IF.. >r 2
3fe0: 6e 69 70 20 72 3e 20 75 6e 6c 6f 6f 70 20 20 45 nip r> unloop E
3ff0: 58 49 54 0a 09 54 48 45 4e 20 20 64 72 6f 70 20 XIT..THEN drop
4000: 32 64 72 6f 70 0a 20 20 20 20 63 65 6c 6c 20 2b 2drop. cell +
4010: 4c 4f 4f 50 0a 20 20 20 20 73 69 67 70 6b 73 69 LOOP. sigpksi
4020: 7a 65 23 20 2b 20 20 2d 35 20 3b 0a 0a 3a 20 6d ze# + -5 ;..: m
4030: 73 67 2d 73 69 67 3f 20 28 20 61 64 64 72 20 75 sg-sig? ( addr u
4040: 20 2d 2d 20 61 64 64 72 20 75 27 20 66 6c 61 67 -- addr u' flag
4050: 20 29 0a 20 20 20 20 73 6b 69 70 2d 73 69 67 3f ). skip-sig?
4060: 20 40 20 49 46 20 20 20 71 75 69 63 6b 73 69 67 @ IF quicksig
4070: 28 20 70 6b 2d 71 75 69 63 6b 2d 73 69 67 3f 20 ( pk-quick-sig?
4080: 29 65 6c 73 65 28 20 70 6b 2d 64 61 74 65 3f 20 )else( pk-date?
4090: 29 0a 20 20 20 20 45 4c 53 45 20 20 70 6b 2d 73 ). ELSE pk-s
40a0: 69 67 3f 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 6d ig? THEN ;..: m
40b0: 73 67 2d 64 65 63 3f 2d 73 69 67 3f 20 28 20 61 sg-dec?-sig? ( a
40c0: 64 64 72 20 75 20 2d 2d 20 61 64 64 72 27 20 75 ddr u -- addr' u
40d0: 27 20 66 6c 61 67 20 29 0a 20 20 20 20 32 64 75 ' flag ). 2du
40e0: 70 20 32 20 2d 20 2b 20 63 40 20 24 38 30 20 61 p 2 - + c@ $80 a
40f0: 6e 64 20 49 46 20 20 6d 73 67 2d 64 65 63 2d 73 nd IF msg-dec-s
4100: 69 67 3f 20 20 45 4c 53 45 20 20 6d 73 67 2d 73 ig? ELSE msg-s
4110: 69 67 3f 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 72 ig? THEN ;..: r
4120: 65 70 6c 61 63 65 2d 73 69 67 20 7b 20 61 64 64 eplace-sig { add
4130: 72 73 69 67 20 75 73 69 67 20 61 64 64 72 6d 73 rsig usig addrms
4140: 67 20 75 6d 73 67 20 2d 2d 20 7d 0a 20 20 20 20 g umsg -- }.
4150: 61 64 64 72 73 69 67 20 75 73 69 67 20 61 64 64 addrsig usig add
4160: 72 6d 73 67 20 75 6d 73 67 20 75 73 69 67 20 2d rmsg umsg usig -
4170: 20 5b 3a 20 74 79 70 65 20 74 79 70 65 20 3b 5d [: type type ;]
4180: 20 24 74 6d 70 0a 20 20 20 20 32 64 75 70 20 6d $tmp. 2dup m
4190: 73 67 2d 64 65 63 3f 2d 73 69 67 3f 20 21 21 73 sg-dec?-sig? !!s
41a0: 69 67 21 21 20 32 64 72 6f 70 20 61 64 64 72 6d ig!! 2drop addrm
41b0: 73 67 20 75 6d 73 67 20 73 6d 6f 76 65 20 3b 0a sg umsg smove ;.
41c0: 3a 20 6e 65 77 2d 6f 74 72 73 69 67 20 28 20 61 : new-otrsig ( a
41d0: 64 64 72 20 75 20 66 6c 61 67 20 2d 2d 20 61 64 ddr u flag -- ad
41e0: 64 72 73 69 67 20 75 73 69 67 20 29 0a 20 20 20 drsig usig ).
41f0: 20 3e 72 20 32 64 75 70 20 73 74 61 72 74 64 61 >r 2dup startda
4200: 74 65 40 20 6f 6c 64 3e 6f 74 72 0a 20 20 20 20 te@ old>otr.
4210: 70 72 65 64 61 74 65 2d 6b 65 79 20 6b 65 63 63 predate-key kecc
4220: 61 6b 23 20 63 3a 6b 65 79 40 20 63 3a 6b 65 79 ak# c:key@ c:key
4230: 23 20 73 6d 6f 76 65 0a 20 20 20 20 5b 3a 20 73 # smove. [: s
4240: 6b 74 6d 70 20 70 6b 6d 6f 64 20 73 6b 40 20 64 ktmp pkmod sk@ d
4250: 72 6f 70 20 3e 6d 6f 64 6b 65 79 20 2e 65 6e 63 rop >modkey .enc
4260: 73 69 67 6e 2d 72 65 73 74 20 3b 5d 0a 20 20 20 sign-rest ;].
4270: 20 5b 27 5d 20 2e 73 69 67 20 72 40 20 73 65 6c ['] .sig r@ sel
4280: 65 63 74 20 24 74 6d 70 0a 20 20 20 20 32 64 75 ect $tmp. 2du
4290: 70 20 2b 20 32 20 2d 20 72 3e 20 73 77 61 70 20 p + 2 - r> swap
42a0: 6f 72 63 21 0a 20 20 20 20 28 20 32 64 75 70 20 orc!. ( 2dup
42b0: 64 75 6d 70 20 29 20 31 20 36 34 73 20 2f 73 74 dump ) 1 64s /st
42c0: 72 69 6e 67 20 3b 0a 0a 3a 6e 6f 6e 61 6d 65 20 ring ;..:noname
42d0: 7b 20 73 69 67 20 75 27 20 61 64 64 72 20 75 20 { sig u' addr u
42e0: 2d 2d 20 7d 0a 20 20 20 20 75 27 20 36 34 27 2b -- }. u' 64'+
42f0: 20 75 20 3d 20 20 75 20 73 69 67 73 69 7a 65 23 u = u sigsize#
4300: 20 3d 20 61 6e 64 20 49 46 0a 09 6c 61 73 74 23 = and IF..last#
4310: 20 3e 72 20 6c 61 73 74 23 20 24 40 20 3e 67 72 >r last# $@ >gr
4320: 6f 75 70 0a 09 61 64 64 72 20 75 20 73 74 61 72 oup..addr u star
4330: 74 64 61 74 65 40 20 36 34 64 75 70 20 64 61 74 tdate@ 64dup dat
4340: 65 3e 69 20 3e 72 20 36 34 23 31 20 36 34 2b 20 e>i >r 64#1 64+
4350: 64 61 74 65 3e 69 27 20 72 3e 0a 09 32 64 75 70 date>i' r>..2dup
4360: 20 3d 20 49 46 20 20 2e 22 20 20 5b 6f 74 72 69 = IF ." [otri
4370: 66 69 65 64 5d 20 22 20 20 61 64 64 72 20 75 20 fied] " addr u
4380: 73 74 61 72 74 64 61 74 65 40 20 2e 74 69 63 6b startdate@ .tick
4390: 73 20 20 54 48 45 4e 0a 09 55 2b 44 4f 0a 09 20 s THEN..U+DO..
43a0: 20 20 20 49 20 6d 73 67 2d 67 72 6f 75 70 2d 6f I msg-group-o
43b0: 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 40 .msg:log[] $[]@
43c0: 0a 09 20 20 20 20 32 64 75 70 20 2b 20 32 20 2d .. 2dup + 2 -
43d0: 20 63 40 20 24 38 30 20 61 6e 64 20 49 46 20 20 c@ $80 and IF
43e0: 6d 73 67 2d 64 65 63 2d 73 69 67 3f 20 64 72 6f msg-dec-sig? dro
43f0: 70 20 20 54 48 45 4e 0a 09 20 20 20 20 32 64 75 p THEN.. 2du
4400: 70 20 64 75 70 20 73 69 67 70 6b 73 69 7a 65 23 p dup sigpksize#
4410: 20 2d 20 2f 73 74 72 69 6e 67 20 6b 65 79 7c 20 - /string key|
4420: 6d 73 67 3a 69 64 24 20 73 74 72 3d 20 49 46 0a msg:id$ str= IF.
4430: 09 09 64 75 70 20 75 20 2d 20 2f 73 74 72 69 6e ..dup u - /strin
4440: 67 20 61 64 64 72 20 75 20 73 74 72 3d 20 49 46 g addr u str= IF
4450: 0a 09 09 20 20 20 20 2e 22 20 20 4f 54 52 69 66 ... ." OTRif
4460: 79 20 23 22 20 49 20 75 2e 0a 09 09 20 20 20 20 y #" I u....
4470: 73 69 67 20 75 27 20 49 20 6d 73 67 2d 67 72 6f sig u' I msg-gro
4480: 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 up-o .msg:log[]
4490: 24 5b 5d 40 20 72 65 70 6c 61 63 65 2d 73 69 67 $[]@ replace-sig
44a0: 0a 09 09 20 20 20 20 73 61 76 65 2d 6d 73 67 73 ... save-msgs
44b0: 26 0a 09 09 45 4c 53 45 0a 09 09 20 20 20 20 2e &...ELSE... .
44c0: 22 20 20 5b 4f 54 52 69 66 69 65 64 5d 20 23 22 " [OTRified] #"
44d0: 20 49 20 75 2e 0a 09 09 54 48 45 4e 0a 09 20 20 I u....THEN..
44e0: 20 20 45 4c 53 45 0a 09 09 2e 22 20 20 49 44 20 ELSE...." ID
44f0: 6d 69 73 6d 61 74 63 68 3a 20 22 0a 09 09 32 64 mismatch: "...2d
4500: 75 70 20 64 75 70 20 73 69 67 70 6b 73 69 7a 65 up dup sigpksize
4510: 23 20 2d 20 2f 73 74 72 69 6e 67 20 6b 65 79 7c # - /string key|
4520: 20 38 35 74 79 70 65 20 73 70 61 63 65 0a 09 09 85type space...
4530: 6d 73 67 3a 69 64 24 20 38 35 74 79 70 65 20 66 msg:id$ 85type f
4540: 6f 72 74 68 3a 63 72 0a 09 09 32 64 72 6f 70 0a orth:cr...2drop.
4550: 09 20 20 20 20 54 48 45 4e 0a 09 4c 4f 4f 50 0a . THEN..LOOP.
4560: 09 72 3e 20 74 6f 20 6c 61 73 74 23 0a 20 20 20 .r> to last#.
4570: 20 54 48 45 4e 20 3b 20 6d 73 67 2d 63 6c 61 73 THEN ; msg-clas
4580: 73 20 69 73 20 6d 73 67 3a 6f 74 72 69 66 79 0a s is msg:otrify.
4590: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 2d 2d 20 29 0a .:noname ( -- ).
45a0: 20 20 20 20 66 6f 72 74 68 3a 63 72 20 3b 20 6d forth:cr ; m
45b0: 73 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a sg-class is msg:
45c0: 65 6e 64 0a 0a 5c 67 20 0a 5c 67 20 23 23 23 20 end..\g .\g ###
45d0: 67 72 6f 75 70 20 64 65 73 63 72 69 70 74 69 6f group descriptio
45e0: 6e 20 63 6f 6d 6d 61 6e 64 73 20 23 23 23 0a 5c n commands ###.\
45f0: 67 20 0a 0a 68 61 73 68 3a 20 67 72 6f 75 70 23 g ..hash: group#
4600: 0a 0a 73 74 61 74 69 63 2d 61 20 74 6f 20 61 6c ..static-a to al
4610: 6c 6f 63 61 74 65 72 0a 61 6c 69 67 6e 20 68 65 locater.align he
4620: 72 65 0a 67 72 6f 75 70 73 2d 63 6c 61 73 73 20 re.groups-class
4630: 6e 65 77 20 43 6f 6e 73 74 61 6e 74 20 67 72 6f new Constant gro
4640: 75 70 2d 6f 0a 64 79 6e 61 6d 69 63 2d 61 20 74 up-o.dynamic-a t
4650: 6f 20 61 6c 6c 6f 63 61 74 65 72 0a 68 65 72 65 o allocater.here
4660: 20 6f 76 65 72 20 2d 20 32 43 6f 6e 73 74 61 6e over - 2Constan
4670: 74 20 73 61 6d 70 6c 65 2d 67 72 6f 75 70 24 0a t sample-group$.
4680: 0a 3a 20 6c 61 73 74 3e 6f 20 28 20 2d 2d 20 29 .: last>o ( -- )
4690: 0a 20 20 20 20 5c 47 20 75 73 65 20 6c 61 73 74 . \G use last
46a0: 20 68 61 73 68 20 61 63 63 65 73 73 20 61 73 20 hash access as
46b0: 6f 62 6a 65 63 74 0a 20 20 20 20 6c 61 73 74 23 object. last#
46c0: 20 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 cell+ $@ drop c
46d0: 65 6c 6c 2b 20 3e 6f 20 72 64 72 6f 70 20 3b 0a ell+ >o rdrop ;.
46e0: 0a 3a 20 6d 61 6b 65 2d 67 72 6f 75 70 20 28 20 .: make-group (
46f0: 61 64 64 72 20 75 20 2d 2d 20 6f 3a 67 72 6f 75 addr u -- o:grou
4700: 70 20 29 0a 20 20 20 20 73 61 6d 70 6c 65 2d 67 p ). sample-g
4710: 72 6f 75 70 24 20 32 6f 76 65 72 20 67 72 6f 75 roup$ 2over grou
4720: 70 23 20 23 21 20 6c 61 73 74 3e 6f 20 74 6f 20 p# #! last>o to
4730: 67 72 6f 75 70 73 3a 69 64 24 20 3b 0a 0a 63 6d groups:id$ ;..cm
4740: 64 2d 74 61 62 6c 65 20 24 40 20 69 6e 68 65 72 d-table $@ inher
4750: 69 74 2d 74 61 62 6c 65 20 67 72 6f 75 70 2d 74 it-table group-t
4760: 61 62 6c 65 0a 0a 73 63 6f 70 65 7b 20 6e 65 74 able..scope{ net
4770: 32 6f 2d 62 61 73 65 0a 0a 24 32 30 20 6e 65 74 2o-base..$20 net
4780: 32 6f 3a 20 67 72 6f 75 70 2d 6e 61 6d 65 20 28 2o: group-name (
4790: 20 24 3a 6e 61 6d 65 20 2d 2d 20 29 20 5c 67 20 $:name -- ) \g
47a0: 67 72 6f 75 70 20 73 79 6d 62 6f 6c 69 63 20 6e group symbolic n
47b0: 61 6d 65 0a 20 20 20 20 24 3e 20 6d 61 6b 65 2d ame. $> make-
47c0: 67 72 6f 75 70 20 3b 0a 2b 6e 65 74 32 6f 3a 20 group ;.+net2o:
47d0: 67 72 6f 75 70 2d 69 64 20 28 20 24 3a 67 72 6f group-id ( $:gro
47e0: 75 70 20 2d 2d 20 29 20 5c 67 20 67 72 6f 75 70 up -- ) \g group
47f0: 20 69 64 2c 20 69 73 20 61 20 70 75 62 6b 65 79 id, is a pubkey
4800: 0a 20 20 20 20 67 72 6f 75 70 2d 6f 20 6f 20 3d . group-o o =
4810: 20 21 21 6e 6f 2d 67 72 6f 75 70 2d 6e 61 6d 65 !!no-group-name
4820: 21 21 20 24 3e 20 74 6f 20 67 72 6f 75 70 73 3a !! $> to groups:
4830: 69 64 24 20 3b 0a 2b 6e 65 74 32 6f 3a 20 67 72 id$ ;.+net2o: gr
4840: 6f 75 70 2d 6d 65 6d 62 65 72 20 28 20 24 3a 6d oup-member ( $:m
4850: 65 6d 62 65 72 6b 65 79 20 2d 2d 20 29 20 5c 67 emberkey -- ) \g
4860: 20 61 64 64 20 6d 65 6d 62 65 72 20 6b 65 79 0a add member key.
4870: 20 20 20 20 67 72 6f 75 70 2d 6f 20 6f 20 3d 20 group-o o =
4880: 21 21 6e 6f 2d 67 72 6f 75 70 2d 6e 61 6d 65 21 !!no-group-name!
4890: 21 20 24 3e 20 67 72 6f 75 70 73 3a 6d 65 6d 62 ! $> groups:memb
48a0: 65 72 5b 5d 20 24 2b 5b 5d 21 20 3b 0a 2b 6e 65 er[] $+[]! ;.+ne
48b0: 74 32 6f 3a 20 67 72 6f 75 70 2d 61 64 6d 69 6e t2o: group-admin
48c0: 20 28 20 24 3a 61 64 6d 69 6e 6b 65 79 20 2d 2d ( $:adminkey --
48d0: 20 29 20 5c 67 20 73 65 74 20 61 64 6d 69 6e 20 ) \g set admin
48e0: 6b 65 79 0a 20 20 20 20 67 72 6f 75 70 2d 6f 20 key. group-o
48f0: 6f 20 3d 20 21 21 6e 6f 2d 67 72 6f 75 70 2d 6e o = !!no-group-n
4900: 61 6d 65 21 21 20 24 3e 20 67 72 6f 75 70 73 3a ame!! $> groups:
4910: 61 64 6d 69 6e 20 73 65 63 21 20 3b 0a 2b 6e 65 admin sec! ;.+ne
4920: 74 32 6f 3a 20 67 72 6f 75 70 2d 70 65 72 6d 73 t2o: group-perms
4930: 20 28 20 36 34 75 20 2d 2d 20 29 20 5c 67 20 70 ( 64u -- ) \g p
4940: 65 72 6d 69 73 73 69 6f 6e 2f 6d 6f 64 65 73 20 ermission/modes
4950: 62 69 74 6d 61 73 6b 0a 20 20 20 20 67 72 6f 75 bitmask. grou
4960: 70 2d 6f 20 6f 20 3d 20 21 21 6e 6f 2d 67 72 6f p-o o = !!no-gro
4970: 75 70 2d 6e 61 6d 65 21 21 20 74 6f 20 67 72 6f up-name!! to gro
4980: 75 70 73 3a 70 65 72 6d 73 23 20 3b 0a 0a 7d 73 ups:perms# ;..}s
4990: 63 6f 70 65 0a 0a 67 72 6f 75 70 2d 74 61 62 6c cope..group-tabl
49a0: 65 20 24 73 61 76 65 0a 0a 67 72 6f 75 70 2d 74 e $save..group-t
49b0: 61 62 6c 65 20 40 20 67 72 6f 75 70 2d 6f 20 2e able @ group-o .
49c0: 74 6f 6b 65 6e 2d 74 61 62 6c 65 20 21 0a 0a 27 token-table !..'
49d0: 20 63 6f 6e 74 65 78 74 2d 74 61 62 6c 65 20 69 context-table i
49e0: 73 20 67 65 6e 2d 74 61 62 6c 65 0a 0a 3a 20 2e s gen-table..: .
49f0: 63 68 61 74 73 2f 67 72 6f 75 70 20 28 20 2d 2d chats/group ( --
4a00: 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 70 6b addr u ). pk
4a10: 40 20 70 6b 63 20 73 77 61 70 20 6d 6f 76 65 20 @ pkc swap move
4a20: 20 73 6b 40 20 73 6b 63 20 73 77 61 70 20 6d 6f sk@ skc swap mo
4a30: 76 65 20 5c 20 6e 6f 72 6d 61 6c 69 7a 65 20 70 ve \ normalize p
4a40: 6b 63 0a 20 20 20 20 70 6b 63 20 6b 65 79 73 69 kc. pkc keysi
4a50: 7a 65 20 33 20 2a 20 5c 20 68 61 73 68 20 6f 66 ze 3 * \ hash of
4a60: 20 70 6b 63 2b 70 6b 31 2b 73 6b 63 20 6b 65 79 pkc+pk1+skc key
4a70: 65 64 20 77 69 74 68 20 22 67 72 6f 75 70 22 0a ed with "group".
4a80: 20 20 20 20 22 67 72 6f 75 70 22 20 6b 65 79 65 "group" keye
4a90: 64 2d 68 61 73 68 23 31 32 38 20 2e 63 68 61 74 d-hash#128 .chat
4aa0: 73 2f 20 3b 0a 0a 3a 20 72 65 61 64 2d 63 68 61 s/ ;..: read-cha
4ab0: 74 67 72 6f 75 70 73 20 28 20 2d 2d 20 29 0a 20 tgroups ( -- ).
4ac0: 20 20 20 30 20 2e 2e 63 68 61 74 73 2f 67 72 6f 0 ..chats/gro
4ad0: 75 70 20 5b 3a 20 74 79 70 65 20 2e 22 20 2e 76 up [: type ." .v
4ae0: 32 6f 22 20 3b 5d 20 24 74 6d 70 0a 20 20 20 20 2o" ;] $tmp.
4af0: 32 64 75 70 20 66 69 6c 65 2d 73 74 61 74 75 73 2dup file-status
4b00: 20 6e 69 70 20 6e 6f 2d 66 69 6c 65 23 20 3d 20 nip no-file# =
4b10: 49 46 20 20 32 64 72 6f 70 20 20 45 58 49 54 20 IF 2drop EXIT
4b20: 20 54 48 45 4e 0a 20 20 20 20 64 65 63 72 79 70 THEN. decryp
4b30: 74 40 20 67 72 6f 75 70 2d 6f 20 2e 64 6f 2d 63 t@ group-o .do-c
4b40: 6d 64 2d 6c 6f 6f 70 20 20 65 6e 63 2d 66 69 6c md-loop enc-fil
4b50: 65 20 24 66 72 65 65 20 3b 0a 0a 61 6c 73 6f 20 e $free ;..also
4b60: 6e 65 74 32 6f 2d 62 61 73 65 0a 0a 3a 20 73 65 net2o-base..: se
4b70: 72 69 61 6c 69 7a 65 2d 63 68 61 74 67 72 6f 75 rialize-chatgrou
4b80: 70 20 28 20 6c 61 73 74 23 20 2d 2d 20 29 0a 20 p ( last# -- ).
4b90: 20 20 20 64 75 70 20 24 40 20 32 64 75 70 20 24 dup $@ 2dup $
4ba0: 2c 20 67 72 6f 75 70 2d 6e 61 6d 65 0a 20 20 20 , group-name.
4bb0: 20 72 6f 74 20 63 65 6c 6c 2b 20 24 40 20 64 72 rot cell+ $@ dr
4bc0: 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a 20 20 20 20 op cell+ >o.
4bd0: 67 72 6f 75 70 73 3a 69 64 24 20 64 75 70 20 49 groups:id$ dup I
4be0: 46 0a 09 32 74 75 63 6b 20 73 74 72 3d 20 30 3d F..2tuck str= 0=
4bf0: 20 49 46 20 20 24 2c 20 67 72 6f 75 70 2d 69 64 IF $, group-id
4c00: 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20 20 54 ELSE 2drop T
4c10: 48 45 4e 0a 20 20 20 20 45 4c 53 45 20 20 32 64 HEN. ELSE 2d
4c20: 72 6f 70 20 32 64 72 6f 70 20 20 54 48 45 4e 0a rop 2drop THEN.
4c30: 20 20 20 20 67 72 6f 75 70 73 3a 6d 65 6d 62 65 groups:membe
4c40: 72 5b 5d 20 5b 3a 20 24 2c 20 67 72 6f 75 70 2d r[] [: $, group-
4c50: 6d 65 6d 62 65 72 20 3b 5d 20 24 5b 5d 6d 61 70 member ;] $[]map
4c60: 0a 20 20 20 20 67 72 6f 75 70 73 3a 61 64 6d 69 . groups:admi
4c70: 6e 20 73 65 63 40 20 64 75 70 20 49 46 20 20 73 n sec@ dup IF s
4c80: 65 63 24 2c 20 67 72 6f 75 70 2d 61 64 6d 69 6e ec$, group-admin
4c90: 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20 20 54 ELSE 2drop T
4ca0: 48 45 4e 0a 20 20 20 20 67 72 6f 75 70 73 3a 70 HEN. groups:p
4cb0: 65 72 6d 73 23 20 36 34 64 75 70 20 36 34 2d 30 erms# 64dup 64-0
4cc0: 3c 3e 20 49 46 20 20 6c 69 74 2c 20 67 72 6f 75 <> IF lit, grou
4cd0: 70 2d 70 65 72 6d 73 20 20 45 4c 53 45 20 20 36 p-perms ELSE 6
4ce0: 34 64 72 6f 70 20 20 54 48 45 4e 0a 20 20 20 20 4drop THEN.
4cf0: 6f 3e 20 3b 0a 0a 70 72 65 76 69 6f 75 73 0a 0a o> ;..previous..
4d00: 3a 20 61 64 6d 69 6e 3e 70 6b 20 28 20 2d 2d 20 : admin>pk ( --
4d10: 29 0a 20 20 20 20 67 72 6f 75 70 73 3a 61 64 6d ). groups:adm
4d20: 69 6e 20 73 65 63 40 20 64 72 6f 70 20 64 75 70 in sec@ drop dup
4d30: 20 73 6b 2d 6d 61 73 6b 0a 20 20 20 20 6b 65 79 sk-mask. key
4d40: 73 69 7a 65 20 61 64 64 72 20 67 72 6f 75 70 73 size addr groups
4d50: 3a 69 64 24 20 24 21 6c 65 6e 0a 20 20 20 20 67 :id$ $!len. g
4d60: 72 6f 75 70 73 3a 69 64 24 20 64 72 6f 70 20 73 roups:id$ drop s
4d70: 6b 3e 70 6b 20 3b 0a 0a 3a 20 67 65 6e 2d 61 64 k>pk ;..: gen-ad
4d80: 6d 69 6e 2d 6b 65 79 20 28 20 2d 2d 20 29 0a 20 min-key ( -- ).
4d90: 20 20 20 24 32 30 20 72 6e 67 24 20 67 72 6f 75 $20 rng$ grou
4da0: 70 73 3a 61 64 6d 69 6e 20 73 65 63 21 20 61 64 ps:admin sec! ad
4db0: 6d 69 6e 3e 70 6b 20 3b 0a 0a 3a 20 73 61 76 65 min>pk ;..: save
4dc0: 2d 63 68 61 74 67 72 6f 75 70 73 20 28 20 2d 2d -chatgroups ( --
4dd0: 20 29 0a 20 20 20 20 30 20 2e 2e 63 68 61 74 73 ). 0 ..chats
4de0: 2f 67 72 6f 75 70 20 65 6e 63 2d 66 69 6c 65 6e /group enc-filen
4df0: 61 6d 65 20 24 21 0a 20 20 20 20 5b 3a 20 67 72 ame $!. [: gr
4e00: 6f 75 70 23 20 5b 27 5d 20 73 65 72 69 61 6c 69 oup# ['] seriali
4e10: 7a 65 2d 63 68 61 74 67 72 6f 75 70 20 23 6d 61 ze-chatgroup #ma
4e20: 70 20 3b 5d 20 67 65 6e 2d 63 6d 64 20 65 6e 63 p ;] gen-cmd enc
4e30: 2d 66 69 6c 65 20 24 21 62 75 66 0a 20 20 20 20 -file $!buf.
4e40: 70 6b 2d 6f 66 66 20 20 6b 65 79 2d 6c 69 73 74 pk-off key-list
4e50: 20 65 6e 63 66 69 6c 65 2d 72 65 73 74 20 3b 0a encfile-rest ;.
4e60: 0a 56 61 72 69 61 62 6c 65 20 67 72 6f 75 70 2d .Variable group-
4e70: 6c 69 73 74 5b 5d 0a 3a 20 24 69 6e 73 5b 5d 67 list[].: $ins[]g
4e80: 72 6f 75 70 20 28 20 6f 3a 67 72 6f 75 70 20 24 roup ( o:group $
4e90: 61 72 72 61 79 20 2d 2d 20 70 6f 73 20 29 0a 20 array -- pos ).
4ea0: 20 20 20 5c 47 20 69 6e 73 65 72 74 20 4f 28 6c \G insert O(l
4eb0: 6f 67 28 6e 29 29 20 69 6e 74 6f 20 70 72 65 2d og(n)) into pre-
4ec0: 73 6f 72 74 65 64 20 61 72 72 61 79 0a 20 20 20 sorted array.
4ed0: 20 5c 47 20 40 76 61 72 7b 70 6f 73 7d 20 69 73 \G @var{pos} is
4ee0: 20 74 68 65 20 69 6e 73 65 72 74 69 6f 6e 20 6f the insertion o
4ef0: 66 66 73 65 74 20 6f 72 20 2d 31 20 69 66 20 6e ffset or -1 if n
4f00: 6f 74 20 69 6e 73 65 72 74 65 64 0a 20 20 20 20 ot inserted.
4f10: 7b 20 61 5b 5d 20 7d 20 30 20 61 5b 5d 20 24 5b { a[] } 0 a[] $[
4f20: 5d 23 0a 20 20 20 20 42 45 47 49 4e 20 20 32 64 ]#. BEGIN 2d
4f30: 75 70 20 75 3c 20 20 57 48 49 4c 45 20 20 32 64 up u< WHILE 2d
4f40: 75 70 20 2b 20 32 2f 20 7b 20 6c 65 66 74 20 72 up + 2/ { left r
4f50: 69 67 68 74 20 24 23 20 7d 0a 09 20 20 20 20 6f ight $# }.. o
4f60: 20 24 40 20 24 23 20 61 5b 5d 20 24 5b 5d 20 40 $@ $# a[] $[] @
4f70: 20 24 40 20 63 6f 6d 70 61 72 65 20 64 75 70 20 $@ compare dup
4f80: 30 3d 20 49 46 0a 09 09 64 72 6f 70 20 6f 20 63 0= IF...drop o c
4f90: 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c ell+ $@ drop cel
4fa0: 6c 2b 20 2e 67 72 6f 75 70 73 3a 69 64 24 0a 09 l+ .groups:id$..
4fb0: 09 24 23 20 61 5b 5d 20 24 5b 5d 20 40 20 63 65 .$# a[] $[] @ ce
4fc0: 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c ll+ $@ drop cell
4fd0: 2b 20 2e 67 72 6f 75 70 73 3a 69 64 24 20 63 6f + .groups:id$ co
4fe0: 6d 70 61 72 65 20 20 54 48 45 4e 0a 09 20 20 20 mpare THEN..
4ff0: 20 30 3c 20 49 46 20 20 6c 65 66 74 20 24 23 20 0< IF left $#
5000: 20 45 4c 53 45 20 20 24 23 20 31 2b 20 72 69 67 ELSE $# 1+ rig
5010: 68 74 20 20 54 48 45 4e 0a 20 20 20 20 52 45 50 ht THEN. REP
5020: 45 41 54 20 20 64 72 6f 70 20 3e 72 0a 20 20 20 EAT drop >r.
5030: 20 6f 20 7b 20 77 5e 20 69 6e 73 24 30 20 7d 20 o { w^ ins$0 }
5040: 69 6e 73 24 30 20 63 65 6c 6c 20 61 5b 5d 20 72 ins$0 cell a[] r
5050: 40 20 63 65 6c 6c 73 20 24 69 6e 73 20 72 3e 20 @ cells $ins r>
5060: 3b 0a 3a 20 67 72 6f 75 70 73 3e 73 6f 72 74 5b ;.: groups>sort[
5070: 5d 20 28 20 2d 2d 20 29 20 20 67 72 6f 75 70 2d ] ( -- ) group-
5080: 6c 69 73 74 5b 5d 20 24 66 72 65 65 0a 20 20 20 list[] $free.
5090: 20 67 72 6f 75 70 23 20 5b 3a 20 3e 6f 20 67 72 group# [: >o gr
50a0: 6f 75 70 2d 6c 69 73 74 5b 5d 20 24 69 6e 73 5b oup-list[] $ins[
50b0: 5d 67 72 6f 75 70 20 6f 3e 20 64 72 6f 70 20 3b ]group o> drop ;
50c0: 5d 20 23 6d 61 70 20 3b 0a 0a 3a 20 2e 63 68 61 ] #map ;..: .cha
50d0: 74 67 72 6f 75 70 20 28 20 6c 61 73 74 23 20 2d tgroup ( last# -
50e0: 2d 20 29 0a 20 20 20 20 64 75 70 20 24 2e 20 73 - ). dup $. s
50f0: 70 61 63 65 20 64 75 70 20 24 40 20 72 6f 74 20 pace dup $@ rot
5100: 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 cell+ $@ drop ce
5110: 6c 6c 2b 20 3e 6f 0a 20 20 20 20 67 72 6f 75 70 ll+ >o. group
5120: 73 3a 69 64 24 20 32 74 75 63 6b 20 73 74 72 3d s:id$ 2tuck str=
5130: 0a 20 20 20 20 49 46 20 20 2e 22 20 3d 22 20 32 . IF ." =" 2
5140: 64 72 6f 70 0a 20 20 20 20 45 4c 53 45 20 20 27 drop. ELSE '
5150: 27 27 20 65 6d 69 74 20 3c 69 6e 66 6f 3e 20 38 '' emit <info> 8
5160: 35 74 79 70 65 20 3c 64 65 66 61 75 6c 74 3e 20 5type <default>
5170: 27 27 27 20 65 6d 69 74 20 54 48 45 4e 20 73 70 ''' emit THEN sp
5180: 61 63 65 0a 20 20 20 20 67 72 6f 75 70 73 3a 6d ace. groups:m
5190: 65 6d 62 65 72 5b 5d 20 5b 3a 20 27 40 27 20 65 ember[] [: '@' e
51a0: 6d 69 74 20 2e 73 69 6d 70 6c 65 2d 69 64 20 73 mit .simple-id s
51b0: 70 61 63 65 20 3b 5d 20 24 5b 5d 6d 61 70 0a 5c pace ;] $[]map.\
51c0: 20 20 20 20 2e 22 20 61 64 6d 69 6e 20 22 20 67 ." admin " g
51d0: 72 6f 75 70 73 3a 61 64 6d 69 6e 5b 5d 20 5b 3a roups:admin[] [:
51e0: 20 27 40 27 20 65 6d 69 74 20 2e 73 69 6d 70 6c '@' emit .simpl
51f0: 65 2d 69 64 20 73 70 61 63 65 20 3b 5d 20 24 5b e-id space ;] $[
5200: 5d 6d 61 70 0a 20 20 20 20 2e 22 20 2b 22 20 67 ]map. ." +" g
5210: 72 6f 75 70 73 3a 70 65 72 6d 73 23 20 78 36 34 roups:perms# x64
5220: 2e 0a 20 20 20 20 6f 3e 20 63 72 20 3b 0a 3a 20 .. o> cr ;.:
5230: 2e 63 68 61 74 67 72 6f 75 70 73 20 28 20 2d 2d .chatgroups ( --
5240: 20 29 0a 20 20 20 20 67 72 6f 75 70 73 3e 73 6f ). groups>so
5250: 72 74 5b 5d 0a 20 20 20 20 67 72 6f 75 70 2d 6c rt[]. group-l
5260: 69 73 74 5b 5d 20 24 40 20 62 6f 75 6e 64 73 20 ist[] $@ bounds
5270: 3f 44 4f 20 20 49 20 40 20 2e 63 68 61 74 67 72 ?DO I @ .chatgr
5280: 6f 75 70 20 20 63 65 6c 6c 20 2b 4c 4f 4f 50 20 oup cell +LOOP
5290: 3b 0a 0a 3a 20 3f 70 6b 67 72 6f 75 70 20 28 20 ;..: ?pkgroup (
52a0: 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 20 75 addr u -- addr u
52b0: 20 29 0a 20 20 20 20 5c 20 69 66 20 6e 6f 20 67 ). \ if no g
52c0: 72 6f 75 70 20 68 61 73 20 62 65 65 6e 20 73 65 roup has been se
52d0: 6c 65 63 74 65 64 2c 20 75 73 65 20 74 68 65 20 lected, use the
52e0: 70 75 62 6b 65 79 20 61 73 20 67 72 6f 75 70 0a pubkey as group.
52f0: 20 20 20 20 6c 61 73 74 23 20 30 3d 20 49 46 20 last# 0= IF
5300: 20 32 64 75 70 20 2b 20 73 69 67 70 6b 73 69 7a 2dup + sigpksiz
5310: 65 23 20 2d 20 6b 65 79 73 69 7a 65 20 3e 67 72 e# - keysize >gr
5320: 6f 75 70 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 68 oup THEN ;..: h
5330: 61 6e 64 6c 65 2d 6d 73 67 20 28 20 61 64 64 72 andle-msg ( addr
5340: 2d 6f 20 75 2d 6f 20 61 64 64 72 2d 64 65 63 20 -o u-o addr-dec
5350: 75 2d 64 65 63 20 2d 2d 20 29 0a 20 20 20 20 3f u-dec -- ). ?
5360: 70 6b 67 72 6f 75 70 20 32 73 77 61 70 20 3e 6d pkgroup 2swap >m
5370: 73 67 2d 6c 6f 67 0a 20 20 20 20 32 64 75 70 20 sg-log. 2dup
5380: 64 30 3c 3e 20 72 65 70 6c 61 79 2d 6d 6f 64 65 d0<> replay-mode
5390: 20 40 20 30 3d 20 61 6e 64 20 5c 20 64 6f 20 73 @ 0= and \ do s
53a0: 6f 6d 65 74 68 69 6e 67 20 69 66 20 69 74 20 69 omething if it i
53b0: 73 20 6e 65 77 0a 20 20 20 20 49 46 0a 09 32 6f s new. IF..2o
53c0: 76 65 72 20 73 68 6f 77 2d 6d 73 67 0a 09 32 64 ver show-msg..2d
53d0: 75 70 20 70 61 72 65 6e 74 20 2e 70 75 73 68 2d up parent .push-
53e0: 6d 73 67 0a 20 20 20 20 54 48 45 4e 20 20 32 64 msg. THEN 2d
53f0: 72 6f 70 20 32 64 72 6f 70 20 3b 0a 0a 5c 67 20 rop 2drop ;..\g
5400: 0a 5c 67 20 23 23 23 20 6d 65 73 73 61 67 69 6e .\g ### messagin
5410: 67 20 63 6f 6d 6d 61 6e 64 73 20 23 23 23 0a 5c g commands ###.\
5420: 67 20 0a 0a 73 63 6f 70 65 7b 20 6e 65 74 32 6f g ..scope{ net2o
5430: 2d 62 61 73 65 0a 0a 24 33 34 20 6e 65 74 32 6f -base..$34 net2o
5440: 3a 20 6d 65 73 73 61 67 65 20 28 20 2d 2d 20 6f : message ( -- o
5450: 3a 6d 73 67 20 29 20 5c 67 20 70 75 73 68 20 61 :msg ) \g push a
5460: 20 6d 65 73 73 61 67 65 20 6f 62 6a 65 63 74 0a message object.
5470: 20 20 20 20 70 65 72 6d 2d 6d 61 73 6b 20 40 20 perm-mask @
5480: 70 65 72 6d 25 6d 73 67 20 61 6e 64 20 30 3d 20 perm%msg and 0=
5490: 21 21 6d 73 67 2d 70 65 72 6d 21 21 0a 20 20 20 !!msg-perm!!.
54a0: 20 3f 6d 73 67 2d 63 6f 6e 74 65 78 74 20 6e 3a ?msg-context n:
54b0: 3e 6f 20 63 2d 73 74 61 74 65 20 6f 66 66 20 20 >o c-state off
54c0: 30 20 74 6f 20 6c 61 73 74 23 20 3b 0a 0a 6d 73 0 to last# ;..ms
54d0: 67 69 6e 67 2d 74 61 62 6c 65 20 3e 74 61 62 6c ging-table >tabl
54e0: 65 0a 0a 72 65 70 6c 79 2d 74 61 62 6c 65 20 24 e..reply-table $
54f0: 40 20 69 6e 68 65 72 69 74 2d 74 61 62 6c 65 20 @ inherit-table
5500: 6d 73 67 69 6e 67 2d 74 61 62 6c 65 0a 0a 24 32 msging-table..$2
5510: 31 20 6e 65 74 32 6f 3a 20 6d 73 67 2d 67 72 6f 1 net2o: msg-gro
5520: 75 70 20 28 20 24 3a 67 72 6f 75 70 20 2d 2d 20 up ( $:group --
5530: 29 20 5c 67 20 73 65 74 20 67 72 6f 75 70 0a 20 ) \g set group.
5540: 20 20 20 24 3e 20 3e 67 72 6f 75 70 20 3b 0a 2b $> >group ;.+
5550: 6e 65 74 32 6f 3a 20 6d 73 67 2d 6a 6f 69 6e 20 net2o: msg-join
5560: 28 20 24 3a 67 72 6f 75 70 20 2d 2d 20 29 20 5c ( $:group -- ) \
5570: 67 20 6a 6f 69 6e 20 61 20 63 68 61 74 20 67 72 g join a chat gr
5580: 6f 75 70 0a 20 20 20 20 24 3e 20 3e 6c 6f 61 64 oup. $> >load
5590: 2d 67 72 6f 75 70 20 70 61 72 65 6e 74 20 3e 6f -group parent >o
55a0: 0a 20 20 20 20 2b 75 6e 69 71 75 65 2d 63 6f 6e . +unique-con
55b0: 20 2b 63 68 61 74 2d 63 6f 6e 74 72 6f 6c 0a 20 +chat-control.
55c0: 20 20 20 77 61 69 74 2d 74 61 73 6b 20 40 20 3f wait-task @ ?
55d0: 64 75 70 2d 49 46 20 20 3c 68 69 64 65 3e 20 20 dup-IF <hide>
55e0: 54 48 45 4e 0a 20 20 20 20 6f 3e 20 3b 0a 2b 6e THEN. o> ;.+n
55f0: 65 74 32 6f 3a 20 6d 73 67 2d 6c 65 61 76 65 20 et2o: msg-leave
5600: 28 20 24 3a 67 72 6f 75 70 20 2d 2d 20 29 20 5c ( $:group -- ) \
5610: 67 20 6c 65 61 76 65 20 61 20 63 68 61 74 20 67 g leave a chat g
5620: 72 6f 75 70 0a 20 20 20 20 24 3e 20 3e 67 72 6f roup. $> >gro
5630: 75 70 20 70 61 72 65 6e 74 20 6d 73 67 2d 67 72 up parent msg-gr
5640: 6f 75 70 2d 6f 20 2e 6d 73 67 3a 70 65 65 72 73 oup-o .msg:peers
5650: 5b 5d 20 64 65 6c 24 63 65 6c 6c 20 3b 0a 2b 6e [] del$cell ;.+n
5660: 65 74 32 6f 3a 20 6d 73 67 2d 72 65 63 6f 6e 6e et2o: msg-reconn
5670: 65 63 74 20 28 20 24 3a 70 75 62 6b 65 79 2b 61 ect ( $:pubkey+a
5680: 64 64 72 20 2d 2d 20 29 20 5c 67 20 72 65 77 69 ddr -- ) \g rewi
5690: 72 65 20 64 69 73 74 72 69 62 75 74 69 6f 6e 20 re distribution
56a0: 74 72 65 65 0a 20 20 20 20 24 3e 20 24 6d 61 6b tree. $> $mak
56b0: 65 0a 20 20 20 20 3c 65 76 65 6e 74 20 6c 61 73 e. <event las
56c0: 74 2d 6d 73 67 20 32 40 20 65 24 2c 20 65 6c 69 t-msg 2@ e$, eli
56d0: 74 2c 20 6f 20 65 6c 69 74 2c 20 6d 73 67 2d 67 t, o elit, msg-g
56e0: 72 6f 75 70 2d 6f 20 65 6c 69 74 2c 20 3a 3e 63 roup-o elit, :>c
56f0: 68 61 74 2d 72 65 63 6f 6e 6e 65 63 74 0a 20 20 hat-reconnect.
5700: 20 20 70 61 72 65 6e 74 20 2e 77 61 69 74 2d 74 parent .wait-t
5710: 61 73 6b 20 40 20 3f 71 75 65 72 79 2d 74 61 73 ask @ ?query-tas
5720: 6b 20 6f 76 65 72 20 73 65 6c 65 63 74 20 65 76 k over select ev
5730: 65 6e 74 3e 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6d ent> ;.+net2o: m
5740: 73 67 2d 6c 61 73 74 3f 20 28 20 73 74 61 72 74 sg-last? ( start
5750: 20 65 6e 64 20 6e 20 2d 2d 20 29 20 36 34 3e 6e end n -- ) 64>n
5760: 20 6d 73 67 3a 6c 61 73 74 3f 20 3b 0a 2b 6e 65 msg:last? ;.+ne
5770: 74 32 6f 3a 20 6d 73 67 2d 6c 61 73 74 20 28 20 t2o: msg-last (
5780: 24 3a 5b 74 69 63 6b 30 2c 6d 73 67 73 2c 2e 2e $:[tick0,msgs,..
5790: 74 69 63 6b 6e 5d 20 6e 20 2d 2d 20 29 20 36 34 tickn] n -- ) 64
57a0: 3e 6e 20 6d 73 67 3a 6c 61 73 74 20 3b 0a 0a 6e >n msg:last ;..n
57b0: 65 74 32 6f 27 20 6e 65 73 74 73 69 67 20 6e 65 et2o' nestsig ne
57c0: 74 32 6f 3a 20 6d 73 67 2d 6e 65 73 74 73 69 67 t2o: msg-nestsig
57d0: 20 28 20 24 3a 63 6d 64 2b 73 69 67 20 2d 2d 20 ( $:cmd+sig --
57e0: 29 20 5c 67 20 63 68 65 63 6b 20 73 69 67 2b 6e ) \g check sig+n
57f0: 65 73 74 0a 20 20 20 20 24 3e 20 6e 65 73 74 2d est. $> nest-
5800: 73 69 67 20 3f 64 75 70 2d 30 3d 2d 49 46 0a 09 sig ?dup-0=-IF..
5810: 68 61 6e 64 6c 65 2d 6d 73 67 0a 20 20 20 20 45 handle-msg. E
5820: 4c 53 45 20 20 72 65 70 6c 61 79 2d 6d 6f 64 65 LSE replay-mode
5830: 20 40 20 49 46 20 20 64 72 6f 70 20 20 45 4c 53 @ IF drop ELS
5840: 45 20 20 21 21 73 69 67 21 21 20 20 54 48 45 4e E !!sig!! THEN
5850: 0a 09 32 64 72 6f 70 20 32 64 72 6f 70 20 5c 20 ..2drop 2drop \
5860: 62 61 6c 6b 20 6f 6e 20 61 6c 6c 20 77 72 6f 6e balk on all wron
5870: 67 20 73 69 67 6e 61 74 75 72 65 73 0a 20 20 20 g signatures.
5880: 20 54 48 45 4e 20 3b 0a 0a 5c 20 67 65 6e 65 72 THEN ;..\ gener
5890: 61 74 65 20 61 6e 20 65 6e 63 72 79 74 2b 73 69 ate an encryt+si
58a0: 67 6e 20 70 61 63 6b 65 74 0a 0a 3a 20 5d 65 6e gn packet..: ]en
58b0: 63 70 6b 73 69 67 6e 20 28 20 2d 2d 20 29 0a 20 cpksign ( -- ).
58c0: 20 20 20 2b 7a 65 72 6f 31 36 20 6e 65 73 74 24 +zero16 nest$
58d0: 0a 20 20 20 20 30 20 6d 73 67 2d 67 72 6f 75 70 . 0 msg-group
58e0: 2d 6f 20 2e 6d 73 67 3a 6b 65 79 73 5b 5d 20 24 -o .msg:keys[] $
58f0: 5b 5d 40 20 65 6e 63 72 79 70 74 24 0a 20 20 20 []@ encrypt$.
5900: 20 5b 27 5d 20 2e 65 6e 63 73 69 67 6e 20 27 5d ['] .encsign ']
5910: 6e 65 73 74 73 69 67 20 3b 0a 0a 5c 20 6e 65 73 nestsig ;..\ nes
5920: 74 2d 73 69 67 20 66 6f 72 20 6d 73 67 2f 6d 73 t-sig for msg/ms
5930: 67 69 6e 67 20 63 6c 61 73 73 65 73 0a 0a 27 20 ging classes..'
5940: 6d 65 73 73 61 67 65 20 6d 73 67 69 6e 67 2d 63 message msging-c
5950: 6c 61 73 73 20 69 73 20 73 74 61 72 74 2d 72 65 lass is start-re
5960: 71 0a 3a 6e 6f 6e 61 6d 65 20 63 68 65 63 6b 2d q.:noname check-
5970: 64 61 74 65 20 3e 72 20 32 64 75 70 20 72 3e 20 date >r 2dup r>
5980: 3b 20 6d 73 67 69 6e 67 2d 63 6c 61 73 73 20 69 ; msging-class i
5990: 73 20 6e 65 73 74 2d 73 69 67 0a 27 20 6d 65 73 s nest-sig.' mes
59a0: 73 61 67 65 20 6d 73 67 2d 63 6c 61 73 73 20 69 sage msg-class i
59b0: 73 20 73 74 61 72 74 2d 72 65 71 0a 3a 6e 6f 6e s start-req.:non
59c0: 61 6d 65 20 32 64 75 70 20 6d 73 67 2d 64 65 63 ame 2dup msg-dec
59d0: 3f 2d 73 69 67 3f 20 3b 20 6d 73 67 2d 63 6c 61 ?-sig? ; msg-cla
59e0: 73 73 20 69 73 20 6e 65 73 74 2d 73 69 67 0a 0a ss is nest-sig..
59f0: 27 20 63 6f 6e 74 65 78 74 2d 74 61 62 6c 65 20 ' context-table
5a00: 69 73 20 67 65 6e 2d 74 61 62 6c 65 0a 0a 61 6c is gen-table..al
5a10: 73 6f 20 7d 73 63 6f 70 65 0a 0a 6d 73 67 69 6e so }scope..msgin
5a20: 67 2d 74 61 62 6c 65 20 24 73 61 76 65 0a 0a 3a g-table $save..:
5a30: 20 6d 73 67 2d 72 65 70 6c 79 20 28 20 74 61 67 msg-reply ( tag
5a40: 20 2d 2d 20 29 0a 20 20 20 20 2e 22 20 67 6f 74 -- ). ." got
5a50: 20 72 65 70 6c 79 20 22 20 68 65 78 2e 20 70 75 reply " hex. pu
5a60: 62 6b 65 79 20 24 40 20 6b 65 79 3e 6e 69 63 6b bkey $@ key>nick
5a70: 20 66 6f 72 74 68 3a 74 79 70 65 20 66 6f 72 74 forth:type fort
5a80: 68 3a 63 72 20 3b 0a 3a 20 65 78 70 65 63 74 2d h:cr ;.: expect-
5a90: 6d 73 67 20 28 20 6f 3a 63 6f 6e 6e 65 63 74 69 msg ( o:connecti
5aa0: 6f 6e 20 2d 2d 20 29 0a 20 20 20 20 72 65 70 6c on -- ). repl
5ab0: 79 28 20 5b 27 5d 20 6d 73 67 2d 72 65 70 6c 79 y( ['] msg-reply
5ac0: 20 29 65 6c 73 65 28 20 5b 27 5d 20 64 72 6f 70 )else( ['] drop
5ad0: 20 29 20 65 78 70 65 63 74 2d 72 65 70 6c 79 2d ) expect-reply-
5ae0: 78 74 20 2b 63 68 61 74 2d 63 6f 6e 74 72 6f 6c xt +chat-control
5af0: 20 3b 0a 0a 55 73 65 72 20 68 61 73 68 74 6d 70 ;..User hashtmp
5b00: 24 20 20 68 61 73 68 74 6d 70 24 20 6f 66 66 0a $ hashtmp$ off.
5b10: 0a 3a 20 6c 61 73 74 2d 6d 73 67 40 20 28 20 2d .: last-msg@ ( -
5b20: 2d 20 74 69 63 6b 73 20 29 0a 20 20 20 20 6c 61 - ticks ). la
5b30: 73 74 23 20 3e 72 0a 20 20 20 20 6c 61 73 74 23 st# >r. last#
5b40: 20 24 40 20 3e 67 72 6f 75 70 20 6d 73 67 2d 67 $@ >group msg-g
5b50: 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b roup-o .msg:log[
5b60: 5d 20 24 5b 5d 23 20 3f 64 75 70 2d 49 46 0a 09 ] $[]# ?dup-IF..
5b70: 31 2d 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 1- msg-group-o .
5b80: 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 40 20 73 msg:log[] $[]@ s
5b90: 74 61 72 74 64 61 74 65 40 0a 20 20 20 20 45 4c tartdate@. EL
5ba0: 53 45 20 20 36 34 23 30 20 20 54 48 45 4e 20 20 SE 64#0 THEN
5bb0: 20 72 3e 20 74 6f 20 6c 61 73 74 23 20 3b 0a 3a r> to last# ;.:
5bc0: 20 6c 2e 68 61 73 68 73 20 28 20 65 6e 64 20 73 l.hashs ( end s
5bd0: 74 61 72 74 20 2d 2d 20 68 61 73 68 61 64 64 72 tart -- hashaddr
5be0: 20 75 20 29 0a 20 20 20 20 68 61 73 68 74 6d 70 u ). hashtmp
5bf0: 24 20 24 6f 66 66 0a 20 20 20 20 6d 73 67 2d 67 $ $off. msg-g
5c00: 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b roup-o .msg:log[
5c10: 5d 20 24 5b 5d 23 20 49 46 0a 09 5b 3a 20 55 2b ] $[]# IF..[: U+
5c20: 44 4f 20 20 49 20 6d 73 67 2d 67 72 6f 75 70 2d DO I msg-group-
5c30: 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d o .msg:log[] $[]
5c40: 40 20 31 2d 20 64 75 70 20 31 20 36 34 73 20 2d @ 1- dup 1 64s -
5c50: 20 73 61 66 65 2f 73 74 72 69 6e 67 20 66 6f 72 safe/string for
5c60: 74 68 3a 74 79 70 65 0a 09 20 20 4c 4f 4f 50 20 th:type.. LOOP
5c70: 3b 5d 20 68 61 73 68 74 6d 70 24 20 24 65 78 65 ;] hashtmp$ $exe
5c80: 63 20 68 61 73 68 74 6d 70 24 20 24 40 0a 09 5c c hashtmp$ $@..\
5c90: 20 5b 3a 20 32 64 75 70 20 64 75 6d 70 20 3b 5d [: 2dup dump ;]
5ca0: 20 73 74 64 65 72 72 20 6f 75 74 66 69 6c 65 2d stderr outfile-
5cb0: 65 78 65 63 75 74 65 20 5c 20 64 75 6d 70 20 68 execute \ dump h
5cc0: 61 73 68 20 69 6e 70 75 74 73 0a 20 20 20 20 45 ash inputs. E
5cd0: 4c 53 45 20 20 32 64 72 6f 70 20 73 22 20 22 20 LSE 2drop s" "
5ce0: 20 54 48 45 4e 20 5c 20 77 65 20 68 61 76 65 20 THEN \ we have
5cf0: 6e 6f 74 68 69 6e 67 20 79 65 74 0a 20 20 20 20 nothing yet.
5d00: 3e 66 69 6c 65 2d 68 61 73 68 20 31 20 36 34 73 >file-hash 1 64s
5d10: 20 75 6d 69 6e 20 3b 0a 3a 20 69 2e 64 61 74 65 umin ;.: i.date
5d20: 20 28 20 69 20 2d 2d 20 29 0a 20 20 20 20 6d 73 ( i -- ). ms
5d30: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c g-group-o .msg:l
5d40: 6f 67 5b 5d 20 24 5b 5d 40 20 73 74 61 72 74 64 og[] $[]@ startd
5d50: 61 74 65 40 20 36 34 23 30 20 7b 20 36 34 5e 20 ate@ 64#0 { 64^
5d60: 78 20 7d 0a 20 20 20 20 78 20 6c 65 2d 36 34 21 x }. x le-64!
5d70: 20 78 20 31 20 36 34 73 20 66 6f 72 74 68 3a 74 x 1 64s forth:t
5d80: 79 70 65 20 3b 0a 3a 20 69 2e 64 61 74 65 2b 31 ype ;.: i.date+1
5d90: 20 28 20 69 20 2d 2d 20 29 0a 20 20 20 20 6d 73 ( i -- ). ms
5da0: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c g-group-o .msg:l
5db0: 6f 67 5b 5d 20 24 5b 5d 40 20 73 74 61 72 74 64 og[] $[]@ startd
5dc0: 61 74 65 40 20 36 34 23 30 20 7b 20 36 34 5e 20 ate@ 64#0 { 64^
5dd0: 78 20 7d 0a 20 20 20 20 36 34 23 31 20 36 34 2b x }. 64#1 64+
5de0: 20 78 20 6c 65 2d 36 34 21 20 78 20 31 20 36 34 x le-64! x 1 64
5df0: 73 20 66 6f 72 74 68 3a 74 79 70 65 20 3b 0a 3a s forth:type ;.:
5e00: 20 6c 61 73 74 2d 6d 73 67 73 40 20 28 20 73 74 last-msgs@ ( st
5e10: 61 72 74 64 61 74 65 20 65 6e 64 64 61 74 65 20 artdate enddate
5e20: 6e 20 2d 2d 20 61 64 64 72 20 75 20 6e 27 20 29 n -- addr u n' )
5e30: 0a 20 20 20 20 5c 47 20 70 72 69 6e 74 20 6e 20 . \G print n
5e40: 69 6e 74 65 72 76 61 6c 73 20 66 6f 72 20 6d 65 intervals for me
5e50: 73 73 61 67 65 73 20 66 72 6f 6d 20 73 74 61 72 ssages from star
5e60: 74 64 61 74 65 20 74 6f 20 65 6e 64 64 61 74 65 tdate to enddate
5e70: 0a 20 20 20 20 5c 47 20 54 68 65 20 69 6e 74 65 . \G The inte
5e80: 72 76 61 6c 73 20 63 6f 6e 74 61 69 6e 20 74 68 rvals contain th
5e90: 65 20 73 61 6d 65 20 73 69 7a 65 20 6f 66 20 6d e same size of m
5ea0: 65 73 73 61 67 65 73 20 65 78 63 65 70 74 20 74 essages except t
5eb0: 68 65 0a 20 20 20 20 5c 47 20 6c 61 73 74 20 6f he. \G last o
5ec0: 6e 65 2c 20 77 68 69 63 68 20 6d 61 79 20 63 6f ne, which may co
5ed0: 6e 74 61 69 6e 20 6c 65 73 73 20 28 72 6f 75 6e ntain less (roun
5ee0: 64 69 6e 67 20 64 6f 77 6e 29 2e 0a 20 20 20 20 ding down)..
5ef0: 5c 47 20 45 61 63 68 20 69 6e 74 65 72 76 61 6c \G Each interval
5f00: 20 63 6f 6e 74 61 69 6e 73 20 61 20 36 34 20 62 contains a 64 b
5f10: 69 74 20 68 61 73 68 20 6f 66 20 74 68 65 20 6c it hash of the l
5f20: 61 73 74 20 36 34 20 62 69 74 20 6f 66 0a 20 20 ast 64 bit of.
5f30: 20 20 5c 47 20 65 61 63 68 20 6d 65 73 73 61 67 \G each messag
5f40: 65 20 77 69 74 68 69 6e 20 74 68 65 20 69 6e 74 e within the int
5f50: 65 72 76 61 6c 0a 20 20 20 20 6c 61 73 74 23 20 erval. last#
5f60: 3e 72 20 3e 72 20 6c 61 73 74 23 20 24 40 20 3e >r >r last# $@ >
5f70: 67 72 6f 75 70 20 70 75 72 67 65 2d 6c 6f 67 0a group purge-log.
5f80: 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 msg-group-o
5f90: 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 0a .msg:log[] $[]#.
5fa0: 20 20 20 20 49 46 0a 09 64 61 74 65 3e 69 27 20 IF..date>i'
5fb0: 3e 72 20 64 61 74 65 3e 69 27 20 72 3e 20 73 77 >r date>i' r> sw
5fc0: 61 70 0a 09 32 64 75 70 20 2d 20 72 3e 20 6f 76 ap..2dup - r> ov
5fd0: 65 72 20 3e 72 20 31 2d 20 31 20 6d 61 78 20 2f er >r 1- 1 max /
5fe0: 20 30 20 6d 61 78 20 31 2b 20 2d 72 6f 74 0a 09 0 max 1+ -rot..
5ff0: 5b 3a 20 6f 76 65 72 20 3e 72 20 55 2b 44 4f 20 [: over >r U+DO
6000: 20 49 20 69 2e 64 61 74 65 0a 09 20 20 20 20 20 I i.date..
6010: 20 64 75 70 20 49 20 2b 20 49 27 20 75 6d 69 6e dup I + I' umin
6020: 20 49 20 6c 2e 68 61 73 68 73 20 66 6f 72 74 68 I l.hashs forth
6030: 3a 74 79 70 65 0a 09 20 20 64 75 70 20 2b 4c 4f :type.. dup +LO
6040: 4f 50 0a 09 20 20 72 3e 20 64 75 70 20 6d 73 67 OP.. r> dup msg
6050: 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f -group-o .msg:lo
6060: 67 5b 5d 20 24 5b 5d 23 20 75 3c 20 49 46 20 20 g[] $[]# u< IF
6070: 69 2e 64 61 74 65 0a 09 20 20 45 4c 53 45 20 20 i.date.. ELSE
6080: 31 2d 20 69 2e 64 61 74 65 2b 31 20 20 54 48 45 1- i.date+1 THE
6090: 4e 0a 09 20 20 64 72 6f 70 20 3b 5d 20 24 74 6d N.. drop ;] $tm
60a0: 70 20 72 3e 20 5c 20 6f 76 65 72 20 31 20 36 34 p r> \ over 1 64
60b0: 73 20 75 3e 20 2d 0a 20 20 20 20 45 4c 53 45 20 s u> -. ELSE
60c0: 20 72 64 72 6f 70 20 36 34 64 72 6f 70 20 36 34 rdrop 64drop 64
60d0: 64 72 6f 70 20 73 22 20 22 20 20 30 20 54 48 45 drop s" " 0 THE
60e0: 4e 20 20 20 72 3e 20 74 6f 20 6c 61 73 74 23 20 N r> to last#
60f0: 3b 0a 0a 5c 20 73 79 6e 63 20 63 68 61 74 6c 6f ;..\ sync chatlo
6100: 67 20 74 68 72 6f 75 67 68 20 76 69 72 74 75 61 g through virtua
6110: 6c 20 66 69 6c 65 20 61 63 63 65 73 73 0a 0a 74 l file access..t
6120: 65 72 6d 73 65 72 76 65 72 2d 63 6c 61 73 73 20 ermserver-class
6130: 63 6c 61 73 73 0a 65 6e 64 2d 63 6c 61 73 73 20 class.end-class
6140: 6d 73 67 66 73 2d 63 6c 61 73 73 0a 0a 66 69 6c msgfs-class..fil
6150: 65 2d 63 6c 61 73 73 65 73 23 20 43 6f 6e 73 74 e-classes# Const
6160: 61 6e 74 20 6d 73 67 66 73 2d 63 6c 61 73 73 23 ant msgfs-class#
6170: 0a 6d 73 67 66 73 2d 63 6c 61 73 73 20 2b 66 69 .msgfs-class +fi
6180: 6c 65 2d 63 6c 61 73 73 65 73 0a 0a 3a 20 73 61 le-classes..: sa
6190: 76 65 2d 74 6f 2d 6d 73 67 20 28 20 61 64 64 72 ve-to-msg ( addr
61a0: 20 75 20 6e 20 2d 2d 20 29 0a 20 20 20 20 73 74 u n -- ). st
61b0: 61 74 65 2d 61 64 64 72 20 3e 6f 20 20 6d 73 67 ate-addr >o msg
61c0: 66 73 2d 63 6c 61 73 73 23 20 66 73 2d 63 6c 61 fs-class# fs-cla
61d0: 73 73 21 20 77 2f 6f 20 66 73 2d 63 72 65 61 74 ss! w/o fs-creat
61e0: 65 20 6f 3e 20 3b 0a 3a 20 2e 63 68 61 74 2d 66 e o> ;.: .chat-f
61f0: 69 6c 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 ile ( addr u --
6200: 29 0a 20 20 20 20 6f 76 65 72 20 6c 65 2d 36 34 ). over le-64
6210: 40 20 2e 74 69 63 6b 73 20 31 20 36 34 73 20 2f @ .ticks 1 64s /
6220: 73 74 72 69 6e 67 20 20 2e 22 20 2d 3e 22 0a 20 string ." ->".
6230: 20 20 20 6f 76 65 72 20 6c 65 2d 36 34 40 20 2e over le-64@ .
6240: 74 69 63 6b 73 20 31 20 36 34 73 20 2f 73 74 72 ticks 1 64s /str
6250: 69 6e 67 20 20 2e 22 20 40 22 0a 20 20 20 20 2e ing ." @". .
6260: 67 72 6f 75 70 20 3b 0a 69 6e 20 6e 65 74 32 6f group ;.in net2o
6270: 20 3a 20 63 6f 70 79 2d 6d 73 67 20 28 20 66 69 : copy-msg ( fi
6280: 6c 65 6e 61 6d 65 20 75 20 2d 2d 20 29 0a 20 20 lename u -- ).
6290: 20 20 2e 22 20 63 6f 70 79 20 6d 73 67 3a 20 22 ." copy msg: "
62a0: 20 32 64 75 70 20 2e 63 68 61 74 2d 66 69 6c 65 2dup .chat-file
62b0: 20 66 6f 72 74 68 3a 63 72 0a 20 20 20 20 5b 3a forth:cr. [:
62c0: 20 6d 73 67 66 73 2d 63 6c 61 73 73 23 20 75 6c msgfs-class# ul
62d0: 69 74 2c 20 66 69 6c 65 2d 74 79 70 65 20 32 64 it, file-type 2d
62e0: 75 70 20 24 2c 20 72 2f 6f 20 75 6c 69 74 2c 20 up $, r/o ulit,
62f0: 6f 70 65 6e 2d 73 69 7a 65 64 2d 66 69 6c 65 0a open-sized-file.
6300: 20 20 20 20 20 20 66 69 6c 65 2d 72 65 67 23 20 file-reg#
6310: 40 20 73 61 76 65 2d 74 6f 2d 6d 73 67 20 3b 5d @ save-to-msg ;]
6320: 20 6e 32 6f 3e 66 69 6c 65 0a 20 20 20 20 31 20 n2o>file. 1
6330: 66 69 6c 65 2d 63 6f 75 6e 74 20 2b 21 20 3b 0a file-count +! ;.
6340: 0a 24 32 30 20 56 61 6c 75 65 20 6d 61 78 2d 6c .$20 Value max-l
6350: 61 73 74 23 0a 24 32 30 20 56 61 6c 75 65 20 61 ast#.$20 Value a
6360: 73 6b 2d 6c 61 73 74 23 0a 0a 56 61 72 69 61 62 sk-last#..Variab
6370: 6c 65 20 61 73 6b 2d 6d 73 67 2d 66 69 6c 65 73 le ask-msg-files
6380: 5b 5d 0a 0a 3a 20 6d 73 67 3a 6c 61 73 74 3f 20 []..: msg:last?
6390: 28 20 73 74 61 72 74 20 65 6e 64 20 6e 20 2d 2d ( start end n --
63a0: 20 29 0a 20 20 20 20 6c 61 73 74 23 20 24 40 20 ). last# $@
63b0: 24 2c 20 6d 73 67 2d 67 72 6f 75 70 0a 20 20 20 $, msg-group.
63c0: 20 6d 61 78 2d 6c 61 73 74 23 20 75 6d 69 6e 0a max-last# umin.
63d0: 20 20 20 20 6c 61 73 74 2d 6d 73 67 73 40 20 3e last-msgs@ >
63e0: 72 20 24 2c 20 72 3e 20 75 6c 69 74 2c 20 6d 73 r $, r> ulit, ms
63f0: 67 2d 6c 61 73 74 20 3b 0a 3a 20 3f 61 73 6b 2d g-last ;.: ?ask-
6400: 6d 73 67 2d 66 69 6c 65 73 20 28 20 61 64 64 72 msg-files ( addr
6410: 20 75 20 2d 2d 20 29 0a 20 20 20 20 36 34 23 2d u -- ). 64#-
6420: 31 20 36 34 23 30 20 7b 20 36 34 5e 20 73 74 61 1 64#0 { 64^ sta
6430: 72 74 64 20 36 34 5e 20 65 6e 64 64 20 7d 20 5c rtd 64^ endd } \
6440: 20 62 79 74 65 20 6f 72 64 65 72 20 6f 66 20 30 byte order of 0
6450: 20 61 6e 64 20 2d 31 20 64 6f 6e 27 74 20 6d 61 and -1 don't ma
6460: 74 74 65 72 0a 20 20 20 20 6c 61 73 74 23 20 24 tter. last# $
6470: 40 20 3e 67 72 6f 75 70 0a 20 20 20 20 24 3e 20 @ >group. $>
6480: 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 49 27 20 49 bounds ?DO..I' I
6490: 20 36 34 27 2b 20 75 3e 20 49 46 0a 09 20 20 20 64'+ u> IF..
64a0: 20 49 20 6c 65 2d 36 34 40 20 64 61 74 65 3e 69 I le-64@ date>i
64b0: 27 0a 09 20 20 20 20 49 20 36 34 27 2b 20 36 34 '.. I 64'+ 64
64c0: 27 2b 20 6c 65 2d 36 34 40 20 64 61 74 65 3e 69 '+ le-64@ date>i
64d0: 27 20 73 77 61 70 0a 09 20 20 20 20 6c 2e 68 61 ' swap.. l.ha
64e0: 73 68 73 20 64 72 6f 70 20 6c 65 2d 36 34 40 0a shs drop le-64@.
64f0: 09 20 20 20 20 49 20 36 34 27 2b 20 6c 65 2d 36 . I 64'+ le-6
6500: 34 40 20 36 34 3c 3e 20 49 46 0a 09 09 49 20 36 4@ 64<> IF...I 6
6510: 34 40 20 73 74 61 72 74 64 20 6c 65 2d 36 34 40 4@ startd le-64@
6520: 20 36 34 75 6d 69 6e 0a 09 09 49 20 36 34 27 2b 64umin...I 64'+
6530: 20 36 34 27 2b 20 36 34 40 20 65 6e 64 64 20 6c 64'+ 64@ endd l
6540: 65 2d 36 34 40 20 36 34 75 6d 61 78 0a 09 20 20 e-64@ 64umax..
6550: 20 20 45 4c 53 45 0a 09 09 73 74 61 72 74 64 20 ELSE...startd
6560: 6c 65 2d 36 34 40 20 36 34 23 2d 31 20 36 34 3c le-64@ 64#-1 64<
6570: 3e 20 49 46 0a 09 09 20 20 20 20 65 6e 64 64 20 > IF... endd
6580: 73 74 61 72 74 64 20 5b 3a 20 31 20 36 34 73 20 startd [: 1 64s
6590: 66 6f 72 74 68 3a 74 79 70 65 20 31 20 36 34 73 forth:type 1 64s
65a0: 20 66 6f 72 74 68 3a 74 79 70 65 20 6c 61 73 74 forth:type last
65b0: 23 20 24 2e 20 3b 5d 0a 09 09 20 20 20 20 61 73 # $. ;]... as
65c0: 6b 2d 6d 73 67 2d 66 69 6c 65 73 5b 5d 20 64 75 k-msg-files[] du
65d0: 70 20 24 5b 5d 23 20 73 77 61 70 20 24 5b 5d 20 p $[]# swap $[]
65e0: 24 65 78 65 63 0a 09 09 54 48 45 4e 0a 09 09 36 $exec...THEN...6
65f0: 34 23 2d 31 20 36 34 23 30 0a 09 20 20 20 20 54 4#-1 64#0.. T
6600: 48 45 4e 20 20 65 6e 64 64 20 6c 65 2d 36 34 21 HEN endd le-64!
6610: 20 73 74 61 72 74 64 20 6c 65 2d 36 34 21 0a 09 startd le-64!..
6620: 54 48 45 4e 0a 20 20 20 20 32 20 36 34 73 20 2b THEN. 2 64s +
6630: 4c 4f 4f 50 0a 20 20 20 20 73 74 61 72 74 64 20 LOOP. startd
6640: 6c 65 2d 36 34 40 20 36 34 23 2d 31 20 36 34 3c le-64@ 64#-1 64<
6650: 3e 20 49 46 0a 09 65 6e 64 64 20 73 74 61 72 74 > IF..endd start
6660: 64 20 5b 3a 20 31 20 36 34 73 20 66 6f 72 74 68 d [: 1 64s forth
6670: 3a 74 79 70 65 20 31 20 36 34 73 20 66 6f 72 74 :type 1 64s fort
6680: 68 3a 74 79 70 65 20 6c 61 73 74 23 20 24 2e 20 h:type last# $.
6690: 3b 5d 0a 09 61 73 6b 2d 6d 73 67 2d 66 69 6c 65 ;]..ask-msg-file
66a0: 73 5b 5d 20 64 75 70 20 24 5b 5d 23 20 73 77 61 s[] dup $[]# swa
66b0: 70 20 24 5b 5d 20 24 65 78 65 63 0a 20 20 20 20 p $[] $exec.
66c0: 54 48 45 4e 20 3b 0a 3a 20 6d 73 67 3a 6c 61 73 THEN ;.: msg:las
66d0: 74 20 28 20 24 3a 5b 74 69 63 6b 30 2c 74 69 63 t ( $:[tick0,tic
66e0: 6b 31 2c 2e 2e 2e 2c 74 69 63 6b 6e 5d 20 6e 20 k1,...,tickn] n
66f0: 2d 2d 20 29 0a 20 20 20 20 6c 61 73 74 23 20 3e -- ). last# >
6700: 72 20 20 61 73 6b 2d 6d 73 67 2d 66 69 6c 65 73 r ask-msg-files
6710: 5b 5d 20 24 5b 5d 6f 66 66 0a 20 20 20 20 66 6f [] $[]off. fo
6720: 72 74 68 3a 2e 20 2e 22 20 4d 65 73 73 61 67 65 rth:. ." Message
6730: 73 3a 22 20 66 6f 72 74 68 3a 63 72 0a 20 20 20 s:" forth:cr.
6740: 20 3f 61 73 6b 2d 6d 73 67 2d 66 69 6c 65 73 20 ?ask-msg-files
6750: 61 73 6b 2d 6d 73 67 2d 66 69 6c 65 73 5b 5d 20 ask-msg-files[]
6760: 24 5b 5d 23 20 49 46 0a 09 70 61 72 65 6e 74 20 $[]# IF..parent
6770: 3e 6f 20 20 65 78 70 65 63 74 2b 73 6c 75 72 70 >o expect+slurp
6780: 0a 09 63 6d 64 62 75 66 23 20 40 20 30 3d 20 49 ..cmdbuf# @ 0= I
6790: 46 20 20 24 31 30 20 62 6c 6f 63 6b 73 69 7a 65 F $10 blocksize
67a0: 21 20 24 31 20 62 6c 6f 63 6b 61 6c 69 67 6e 21 ! $1 blockalign!
67b0: 20 20 54 48 45 4e 0a 09 61 73 6b 2d 6d 73 67 2d THEN..ask-msg-
67c0: 66 69 6c 65 73 5b 5d 20 5b 27 5d 20 6e 65 74 32 files[] ['] net2
67d0: 6f 3a 63 6f 70 79 2d 6d 73 67 20 24 5b 5d 6d 61 o:copy-msg $[]ma
67e0: 70 20 6f 3e 0a 20 20 20 20 45 4c 53 45 0a 09 2e p o>. ELSE...
67f0: 22 20 3d 3d 3d 20 6e 6f 74 68 69 6e 67 20 74 6f " === nothing to
6800: 20 73 79 6e 63 20 3d 3d 3d 22 20 66 6f 72 74 68 sync ===" forth
6810: 3a 63 72 0a 09 70 61 72 65 6e 74 20 2e 73 79 6e :cr..parent .syn
6820: 63 2d 6e 6f 6e 65 2d 78 74 20 5c 20 73 79 6e 63 c-none-xt \ sync
6830: 2d 6e 6f 74 68 69 6e 67 2d 78 74 3f 3f 3f 0a 20 -nothing-xt???.
6840: 20 20 20 54 48 45 4e 0a 20 20 20 20 72 3e 20 74 THEN. r> t
6850: 6f 20 6c 61 73 74 23 20 3b 0a 0a 3a 6e 6f 6e 61 o last# ;..:nona
6860: 6d 65 20 28 20 2d 2d 20 36 34 6c 65 6e 20 29 0a me ( -- 64len ).
6870: 20 20 20 20 5c 20 70 6f 6c 6c 20 73 65 72 69 61 \ poll seria
6880: 6c 69 7a 65 73 20 74 68 65 20 0a 20 20 20 20 66 lizes the . f
6890: 73 2d 6f 75 74 62 75 66 20 24 6f 66 66 0a 20 20 s-outbuf $off.
68a0: 20 20 66 73 2d 70 61 74 68 20 24 40 20 32 20 36 fs-path $@ 2 6
68b0: 34 73 20 2f 73 74 72 69 6e 67 20 3e 67 72 6f 75 4s /string >grou
68c0: 70 0a 20 20 20 20 6d 73 67 2d 6c 6f 67 40 20 6f p. msg-log@ o
68d0: 76 65 72 20 3e 72 0a 20 20 20 20 66 73 2d 70 61 ver >r. fs-pa
68e0: 74 68 20 24 40 20 64 72 6f 70 20 6c 65 2d 36 34 th $@ drop le-64
68f0: 40 20 64 61 74 65 3e 69 20 5c 20 73 74 61 72 74 @ date>i \ start
6900: 20 69 6e 64 65 78 0a 20 20 20 20 66 73 2d 70 61 index. fs-pa
6910: 74 68 20 24 40 20 64 72 6f 70 20 36 34 27 2b 20 th $@ drop 64'+
6920: 6c 65 2d 36 34 40 20 36 34 23 31 20 36 34 2b 20 le-64@ 64#1 64+
6930: 64 61 74 65 3e 69 27 20 5c 20 65 6e 64 20 69 6e date>i' \ end in
6940: 64 65 78 0a 20 20 20 20 6f 76 65 72 20 2d 20 3e dex. over - >
6950: 72 0a 20 20 20 20 63 65 6c 6c 73 20 73 61 66 65 r. cells safe
6960: 2f 73 74 72 69 6e 67 20 72 3e 20 63 65 6c 6c 73 /string r> cells
6970: 20 75 6d 69 6e 0a 20 20 20 20 72 65 71 3f 20 40 umin. req? @
6980: 20 3e 72 20 72 65 71 3f 20 6f 66 66 20 20 73 65 >r req? off se
6990: 72 69 61 6c 69 7a 65 2d 6c 6f 67 20 20 20 72 3e rialize-log r>
69a0: 20 72 65 71 3f 20 21 20 20 66 73 2d 6f 75 74 62 req? ! fs-outb
69b0: 75 66 20 24 21 62 75 66 0a 20 20 20 20 72 3e 20 uf $!buf. r>
69c0: 66 72 65 65 20 74 68 72 6f 77 0a 20 20 20 20 66 free throw. f
69d0: 73 2d 6f 75 74 62 75 66 20 24 40 6c 65 6e 20 75 s-outbuf $@len u
69e0: 3e 36 34 20 3b 20 6d 73 67 66 73 2d 63 6c 61 73 >64 ; msgfs-clas
69f0: 73 20 69 73 20 66 73 2d 70 6f 6c 6c 0a 3a 6e 6f s is fs-poll.:no
6a00: 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 6d 6f name ( addr u mo
6a10: 64 65 20 2d 2d 20 29 0a 20 20 20 20 5c 47 20 61 de -- ). \G a
6a20: 64 64 72 20 75 20 69 73 20 73 74 61 72 74 74 69 ddr u is startti
6a30: 63 6b 20 65 6e 64 74 69 63 6b 20 6e 61 6d 65 20 ck endtick name
6a40: 63 6f 6e 63 61 74 65 6e 61 74 65 64 20 74 6f 67 concatenated tog
6a50: 65 74 68 65 72 0a 20 20 20 20 66 73 2d 63 6c 6f ether. fs-clo
6a60: 73 65 20 64 72 6f 70 20 66 73 2d 70 61 74 68 20 se drop fs-path
6a70: 24 21 20 20 66 73 2d 70 6f 6c 6c 20 66 73 2d 73 $! fs-poll fs-s
6a80: 69 7a 65 21 0a 20 20 20 20 5b 27 5d 20 6e 6f 6f ize!. ['] noo
6a90: 70 20 69 73 20 66 69 6c 65 2d 78 74 0a 3b 20 6d p is file-xt.; m
6aa0: 73 67 66 73 2d 63 6c 61 73 73 20 69 73 20 66 73 sgfs-class is fs
6ab0: 2d 6f 70 65 6e 0a 0a 5c 20 73 79 6e 63 69 6e 67 -open..\ syncing
6ac0: 20 64 6f 6e 65 0a 3a 20 63 68 61 74 2d 73 79 6e done.: chat-syn
6ad0: 63 2d 64 6f 6e 65 20 28 20 67 72 6f 75 70 2d 61 c-done ( group-a
6ae0: 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6d ddr u -- ). m
6af0: 73 67 28 20 2e 22 20 63 68 61 74 2d 73 79 6e 63 sg( ." chat-sync
6b00: 2d 64 6f 6e 65 20 22 20 32 64 75 70 20 66 6f 72 -done " 2dup for
6b10: 74 68 3a 74 79 70 65 20 66 6f 72 74 68 3a 63 72 th:type forth:cr
6b20: 20 29 0a 20 20 20 20 3e 67 72 6f 75 70 20 64 69 ). >group di
6b30: 73 70 6c 61 79 2d 73 79 6e 63 2d 64 6f 6e 65 20 splay-sync-done
6b40: 21 73 61 76 65 2d 61 6c 6c 2d 6d 73 67 73 0a 20 !save-all-msgs.
6b50: 20 20 20 6e 65 74 32 6f 2d 63 6f 64 65 20 65 78 net2o-code ex
6b60: 70 65 63 74 2d 6d 73 67 20 63 6c 6f 73 65 2d 61 pect-msg close-a
6b70: 6c 6c 20 6e 65 74 32 6f 3a 67 65 6e 2d 72 65 73 ll net2o:gen-res
6b80: 65 74 20 65 6e 64 2d 63 6f 64 65 0a 20 20 20 20 et end-code.
6b90: 6e 65 74 32 6f 3a 63 6c 6f 73 65 2d 61 6c 6c 0a net2o:close-all.
6ba0: 20 20 20 20 2e 22 20 3d 3d 3d 20 73 79 6e 63 20 ." === sync
6bb0: 64 6f 6e 65 20 3d 3d 3d 22 20 66 6f 72 74 68 3a done ===" forth:
6bc0: 63 72 20 73 79 6e 63 2d 64 6f 6e 65 2d 78 74 20 cr sync-done-xt
6bd0: 3b 0a 65 76 65 6e 74 3a 20 3a 3e 6d 73 67 2d 65 ;.event: :>msg-e
6be0: 76 61 6c 20 28 20 70 61 72 65 6e 74 20 24 70 61 val ( parent $pa
6bf0: 63 6b 20 24 61 64 64 72 20 2d 2d 20 29 0a 20 20 ck $addr -- ).
6c00: 20 20 7b 20 77 5e 20 62 75 66 20 77 5e 20 67 72 { w^ buf w^ gr
6c10: 6f 75 70 20 7d 0a 20 20 20 20 67 72 6f 75 70 20 oup }. group
6c20: 24 40 20 32 20 36 34 73 20 2f 73 74 72 69 6e 67 $@ 2 64s /string
6c30: 20 7b 20 64 3a 20 67 6e 61 6d 65 20 7d 0a 20 20 { d: gname }.
6c40: 20 20 67 6e 61 6d 65 20 3e 67 72 6f 75 70 0a 20 gname >group.
6c50: 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e msg-group-o .
6c60: 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 20 75 msg:log[] $[]# u
6c70: 2e 0a 20 20 20 20 62 75 66 20 24 40 20 74 72 75 .. buf $@ tru
6c80: 65 20 72 65 70 6c 61 79 2d 6d 6f 64 65 20 5b 27 e replay-mode ['
6c90: 5d 20 6d 73 67 2d 65 76 61 6c 20 21 77 72 61 70 ] msg-eval !wrap
6ca0: 70 65 72 0a 20 20 20 20 62 75 66 20 24 66 72 65 per. buf $fre
6cb0: 65 20 3f 73 61 76 65 2d 6d 73 67 0a 20 20 20 20 e ?save-msg.
6cc0: 67 72 6f 75 70 20 24 40 20 2e 63 68 61 74 2d 66 group $@ .chat-f
6cd0: 69 6c 65 20 2e 22 20 20 73 61 76 65 64 20 22 0a ile ." saved ".
6ce0: 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 msg-group-o
6cf0: 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 20 .msg:log[] $[]#
6d00: 75 2e 20 66 6f 72 74 68 3a 63 72 0a 20 20 20 20 u. forth:cr.
6d10: 3e 6f 20 2d 31 20 66 69 6c 65 2d 63 6f 75 6e 74 >o -1 file-count
6d20: 20 2b 21 40 20 31 20 3d 0a 20 20 20 20 49 46 20 +!@ 1 =. IF
6d30: 20 67 6e 61 6d 65 20 63 68 61 74 2d 73 79 6e 63 gname chat-sync
6d40: 2d 64 6f 6e 65 20 20 54 48 45 4e 20 20 67 72 6f -done THEN gro
6d50: 75 70 20 24 66 72 65 65 0a 20 20 20 20 6f 3e 20 up $free. o>
6d60: 3b 0a 3a 20 6d 73 67 2d 66 69 6c 65 2d 64 6f 6e ;.: msg-file-don
6d70: 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 66 73 2d e ( -- ). fs-
6d80: 70 61 74 68 20 24 40 6c 65 6e 20 49 46 0a 09 6d path $@len IF..m
6d90: 73 67 28 20 2e 22 20 6d 73 67 20 66 69 6c 65 20 sg( ." msg file
6da0: 64 6f 6e 65 3a 20 22 20 66 73 2d 70 61 74 68 20 done: " fs-path
6db0: 24 40 20 2e 63 68 61 74 2d 66 69 6c 65 20 66 6f $@ .chat-file fo
6dc0: 72 74 68 3a 63 72 20 29 0a 09 5b 27 5d 20 66 73 rth:cr )..['] fs
6dd0: 2d 66 6c 75 73 68 20 66 69 6c 65 2d 73 65 6d 61 -flush file-sema
6de0: 20 63 2d 73 65 63 74 69 6f 6e 0a 20 20 20 20 54 c-section. T
6df0: 48 45 4e 20 3b 0a 3a 6e 6f 6e 61 6d 65 20 28 20 HEN ;.:noname (
6e00: 61 64 64 72 20 75 20 6d 6f 64 65 20 2d 2d 20 29 addr u mode -- )
6e10: 0a 20 20 20 20 66 73 2d 63 6c 6f 73 65 20 64 72 . fs-close dr
6e20: 6f 70 20 66 73 2d 70 61 74 68 20 24 21 0a 20 20 op fs-path $!.
6e30: 20 20 5b 27 5d 20 6d 73 67 2d 66 69 6c 65 2d 64 ['] msg-file-d
6e40: 6f 6e 65 20 69 73 20 66 69 6c 65 2d 78 74 0a 3b one is file-xt.;
6e50: 20 6d 73 67 66 73 2d 63 6c 61 73 73 20 69 73 20 msgfs-class is
6e60: 66 73 2d 63 72 65 61 74 65 0a 3a 6e 6f 6e 61 6d fs-create.:nonam
6e70: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 75 20 e ( addr u -- u
6e80: 29 0a 20 20 20 20 5b 20 74 65 72 6d 73 65 72 76 ). [ termserv
6e90: 65 72 2d 63 6c 61 73 73 20 3a 3a 20 66 73 2d 72 er-class :: fs-r
6ea0: 65 61 64 20 5d 0a 3b 20 6d 73 67 66 73 2d 63 6c ead ].; msgfs-cl
6eb0: 61 73 73 20 69 73 20 66 73 2d 72 65 61 64 0a 3a ass is fs-read.:
6ec0: 6e 6f 6e 61 6d 65 20 28 20 2d 2d 20 29 0a 09 3c noname ( -- )..<
6ed0: 65 76 65 6e 74 20 70 61 72 65 6e 74 20 65 6c 69 event parent eli
6ee0: 74 2c 20 30 20 66 73 2d 69 6e 62 75 66 20 21 40 t, 0 fs-inbuf !@
6ef0: 20 65 6c 69 74 2c 20 20 30 20 66 73 2d 70 61 74 elit, 0 fs-pat
6f00: 68 20 21 40 20 65 6c 69 74 2c 20 3a 3e 6d 73 67 h !@ elit, :>msg
6f10: 2d 65 76 61 6c 0a 09 70 61 72 65 6e 74 20 2e 77 -eval..parent .w
6f20: 61 69 74 2d 74 61 73 6b 20 40 20 65 76 65 6e 74 ait-task @ event
6f30: 3e 0a 09 66 73 3a 66 73 2d 63 6c 65 61 72 0a 3b >..fs:fs-clear.;
6f40: 20 6d 73 67 66 73 2d 63 6c 61 73 73 20 69 73 20 msgfs-class is
6f50: 66 73 2d 66 6c 75 73 68 20 20 20 20 0a 3a 6e 6f fs-flush .:no
6f60: 6e 61 6d 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 name ( -- ).
6f70: 66 73 2d 70 61 74 68 20 40 20 30 3d 20 3f 45 58 fs-path @ 0= ?EX
6f80: 49 54 0a 20 20 20 20 66 73 2d 69 6e 62 75 66 20 IT. fs-inbuf
6f90: 24 40 6c 65 6e 20 49 46 0a 09 6d 73 67 28 20 2e $@len IF..msg( .
6fa0: 22 20 43 6c 6f 73 69 6e 67 20 66 69 6c 65 20 22 " Closing file "
6fb0: 20 66 73 2d 70 61 74 68 20 24 40 20 2e 63 68 61 fs-path $@ .cha
6fc0: 74 2d 66 69 6c 65 20 66 6f 72 74 68 3a 63 72 20 t-file forth:cr
6fd0: 29 0a 09 66 73 2d 66 6c 75 73 68 0a 20 20 20 20 )..fs-flush.
6fe0: 54 48 45 4e 0a 3b 20 6d 73 67 66 73 2d 63 6c 61 THEN.; msgfs-cla
6ff0: 73 73 20 69 73 20 66 73 2d 63 6c 6f 73 65 0a 3a ss is fs-close.:
7000: 6e 6f 6e 61 6d 65 20 28 20 70 65 72 6d 20 2d 2d noname ( perm --
7010: 20 29 0a 20 20 20 20 70 65 72 6d 25 6d 73 67 20 ). perm%msg
7020: 61 6e 64 20 30 3d 20 21 21 6d 73 67 2d 70 65 72 and 0= !!msg-per
7030: 6d 21 21 0a 3b 20 6d 73 67 66 73 2d 63 6c 61 73 m!!.; msgfs-clas
7040: 73 20 69 73 20 66 73 2d 70 65 72 6d 3f 0a 3a 6e s is fs-perm?.:n
7050: 6f 6e 61 6d 65 20 28 20 2d 2d 20 64 61 74 65 20 oname ( -- date
7060: 70 65 72 6d 20 29 0a 20 20 20 20 36 34 23 30 20 perm ). 64#0
7070: 30 20 3b 20 6d 73 67 66 73 2d 63 6c 61 73 73 20 0 ; msgfs-class
7080: 69 73 20 66 73 2d 67 65 74 2d 73 74 61 74 0a 3a is fs-get-stat.:
7090: 6e 6f 6e 61 6d 65 20 28 20 64 61 74 65 20 70 65 noname ( date pe
70a0: 72 6d 20 2d 2d 20 29 0a 20 20 20 20 64 72 6f 70 rm -- ). drop
70b0: 20 36 34 64 72 6f 70 20 3b 20 6d 73 67 66 73 2d 64drop ; msgfs-
70c0: 63 6c 61 73 73 20 69 73 20 66 73 2d 73 65 74 2d class is fs-set-
70d0: 73 74 61 74 0a 27 20 66 69 6c 65 2d 73 74 61 72 stat.' file-star
70e0: 74 2d 72 65 71 20 6d 73 67 66 73 2d 63 6c 61 73 t-req msgfs-clas
70f0: 73 20 69 73 20 73 74 61 72 74 2d 72 65 71 0a 0a s is start-req..
7100: 5c 20 6d 65 73 73 61 67 65 20 63 6f 6d 70 6f 73 \ message compos
7110: 65 72 0a 0a 3a 20 67 72 6f 75 70 2c 20 28 20 61 er..: group, ( a
7120: 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 24 ddr u -- ). $
7130: 2c 20 6d 73 67 2d 67 72 6f 75 70 20 3b 0a 3a 20 , msg-group ;.:
7140: 3c 6d 73 67 20 28 20 2d 2d 20 29 0a 20 20 20 20 <msg ( -- ).
7150: 73 69 67 6e 5b 20 6d 73 67 2d 67 72 6f 75 70 2d sign[ msg-group-
7160: 6f 20 2e 6d 73 67 3a 3f 6c 6f 63 6b 20 49 46 20 o .msg:?lock IF
7170: 20 2b 7a 65 72 6f 31 36 20 20 54 48 45 4e 20 3b +zero16 THEN ;
7180: 0a 0a 3a 20 6d 73 67 3e 20 28 20 2d 2d 20 29 0a ..: msg> ( -- ).
7190: 20 20 20 20 5c 47 20 65 6e 64 20 61 20 6d 65 73 \G end a mes
71a0: 73 61 67 65 20 62 6c 6f 63 6b 20 62 79 20 61 64 sage block by ad
71b0: 64 69 6e 67 20 61 20 73 69 67 6e 61 74 75 72 65 ding a signature
71c0: 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f . msg-group-o
71d0: 20 2e 6d 73 67 3a 3f 6c 6f 63 6b 20 49 46 20 20 .msg:?lock IF
71e0: 5d 65 6e 63 70 6b 73 69 67 6e 20 20 45 4c 53 45 ]encpksign ELSE
71f0: 20 20 5d 70 6b 73 69 67 6e 20 20 54 48 45 4e 20 ]pksign THEN
7200: 3b 0a 3a 20 6d 73 67 2d 6f 74 72 3e 20 28 20 2d ;.: msg-otr> ( -
7210: 2d 20 29 0a 20 20 20 20 5c 47 20 65 6e 64 20 61 - ). \G end a
7220: 20 6d 65 73 73 61 67 65 20 62 6c 6f 63 6b 20 62 message block b
7230: 79 20 61 64 64 69 6e 67 20 61 20 73 68 6f 72 74 y adding a short
7240: 2d 74 69 6d 65 20 73 69 67 6e 61 74 75 72 65 0a -time signature.
7250: 20 20 20 20 6e 6f 77 3e 6f 74 72 20 6d 73 67 3e now>otr msg>
7260: 20 3b 0a 3a 20 6d 73 67 2d 6c 6f 67 2c 20 28 20 ;.: msg-log, (
7270: 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 -- addr u ).
7280: 6c 61 73 74 2d 73 69 67 6e 65 64 20 32 40 20 3e last-signed 2@ >
7290: 6d 73 67 2d 6c 6f 67 20 3b 0a 0a 70 72 65 76 69 msg-log ;..previ
72a0: 6f 75 73 0a 0a 3a 20 3f 64 65 73 74 70 6b 20 28 ous..: ?destpk (
72b0: 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 27 addr u -- addr'
72c0: 20 75 27 20 29 0a 20 20 20 20 32 64 75 70 20 63 u' ). 2dup c
72d0: 6f 6e 6e 65 63 74 69 6f 6e 20 2e 70 75 62 6b 65 onnection .pubke
72e0: 79 20 24 40 20 6b 65 79 7c 20 73 74 72 3d 20 49 y $@ key| str= I
72f0: 46 20 20 32 64 72 6f 70 20 70 6b 40 20 6b 65 79 F 2drop pk@ key
7300: 7c 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 6c 61 73 | THEN ;..: las
7310: 74 2d 73 69 67 6e 64 61 74 65 40 20 28 20 2d 2d t-signdate@ ( --
7320: 20 36 34 64 61 74 65 20 29 0a 20 20 20 20 6d 73 64date ). ms
7330: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c g-group-o .msg:l
7340: 6f 67 5b 5d 20 24 40 20 64 75 70 20 49 46 0a 09 og[] $@ dup IF..
7350: 2b 20 63 65 6c 6c 2d 20 24 40 20 73 74 61 72 74 + cell- $@ start
7360: 64 61 74 65 40 20 36 34 23 31 20 36 34 2b 0a 20 date@ 64#1 64+.
7370: 20 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20 36 ELSE 2drop 6
7380: 34 23 2d 31 20 20 54 48 45 4e 20 3b 0a 0a 61 6c 4#-1 THEN ;..al
7390: 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 0a 3a 20 so net2o-base.:
73a0: 5b 6d 73 67 2c 5d 20 28 20 78 74 20 2d 2d 20 29 [msg,] ( xt -- )
73b0: 20 20 6c 61 73 74 23 20 3e 72 0a 20 20 20 20 6d last# >r. m
73c0: 73 67 2d 67 72 6f 75 70 24 20 24 40 20 64 75 70 sg-group$ $@ dup
73d0: 20 49 46 20 20 6d 65 73 73 61 67 65 20 3f 64 65 IF message ?de
73e0: 73 74 70 6b 20 32 64 75 70 20 3e 67 72 6f 75 70 stpk 2dup >group
73f0: 20 24 2c 0a 09 65 78 65 63 75 74 65 20 20 65 6e $,..execute en
7400: 64 2d 77 69 74 68 0a 20 20 20 20 45 4c 53 45 20 d-with. ELSE
7410: 20 32 64 72 6f 70 20 64 72 6f 70 20 20 54 48 45 2drop drop THE
7420: 4e 20 20 72 3e 20 74 6f 20 6c 61 73 74 23 20 3b N r> to last# ;
7430: 0a 0a 3a 20 6c 61 73 74 2c 20 28 20 2d 2d 20 29 ..: last, ( -- )
7440: 0a 20 20 20 20 36 34 23 30 20 36 34 23 2d 31 20 . 64#0 64#-1
7450: 61 73 6b 2d 6c 61 73 74 23 20 6c 61 73 74 2d 6d ask-last# last-m
7460: 73 67 73 40 20 3e 72 20 24 2c 20 72 3e 20 75 6c sgs@ >r $, r> ul
7470: 69 74 2c 20 6d 73 67 2d 6c 61 73 74 20 3b 0a 0a it, msg-last ;..
7480: 3a 20 6c 61 73 74 3f 2c 20 28 20 2d 2d 20 29 0a : last?, ( -- ).
7490: 20 20 20 20 6c 61 73 74 2d 73 69 67 6e 64 61 74 last-signdat
74a0: 65 40 20 7b 20 36 34 3a 20 64 61 74 65 20 7d 0a e@ { 64: date }.
74b0: 20 20 20 20 36 34 23 30 20 6c 69 74 2c 20 64 61 64#0 lit, da
74c0: 74 65 20 6c 69 74 2c 20 61 73 6b 2d 6c 61 73 74 te lit, ask-last
74d0: 23 20 75 6c 69 74 2c 20 6d 73 67 2d 6c 61 73 74 # ulit, msg-last
74e0: 3f 0a 20 20 20 20 64 61 74 65 20 36 34 23 2d 31 ?. date 64#-1
74f0: 20 36 34 3c 3e 20 49 46 0a 09 64 61 74 65 20 6c 64<> IF..date l
7500: 69 74 2c 20 36 34 23 2d 31 20 6c 69 74 2c 20 31 it, 64#-1 lit, 1
7510: 20 75 6c 69 74 2c 20 6d 73 67 2d 6c 61 73 74 3f ulit, msg-last?
7520: 0a 20 20 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 73 . THEN ;..: s
7530: 79 6e 63 2d 61 68 65 61 64 3f 2c 20 28 20 2d 2d ync-ahead?, ( --
7540: 20 29 0a 20 20 20 20 6c 61 73 74 2d 73 69 67 6e ). last-sign
7550: 64 61 74 65 40 20 36 34 23 31 20 36 34 2b 20 6c date@ 64#1 64+ l
7560: 69 74 2c 20 36 34 23 2d 31 20 6c 69 74 2c 20 61 it, 64#-1 lit, a
7570: 73 6b 2d 6c 61 73 74 23 20 75 6c 69 74 2c 20 6d sk-last# ulit, m
7580: 73 67 2d 6c 61 73 74 3f 20 3b 0a 0a 3a 20 6a 6f sg-last? ;..: jo
7590: 69 6e 2c 20 28 20 2d 2d 20 29 0a 20 20 20 20 5b in, ( -- ). [
75a0: 3a 20 6d 73 67 2d 6a 6f 69 6e 20 73 79 6e 63 2d : msg-join sync-
75b0: 61 68 65 61 64 3f 2c 0a 20 20 20 20 20 20 3c 6d ahead?,. <m
75c0: 73 67 20 6d 73 67 2d 73 74 61 72 74 20 22 6a 6f sg msg-start "jo
75d0: 69 6e 65 64 22 20 24 2c 20 6d 73 67 2d 61 63 74 ined" $, msg-act
75e0: 69 6f 6e 20 6d 73 67 2d 6f 74 72 3e 20 3b 5d 20 ion msg-otr> ;]
75f0: 5b 6d 73 67 2c 5d 20 3b 0a 0a 3a 20 73 69 6c 65 [msg,] ;..: sile
7600: 6e 74 2d 6a 6f 69 6e 2c 20 28 20 2d 2d 20 29 0a nt-join, ( -- ).
7610: 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 24 20 24 msg-group$ $
7620: 40 20 64 75 70 20 49 46 20 20 6d 65 73 73 61 67 @ dup IF messag
7630: 65 20 24 2c 20 6d 73 67 2d 6a 6f 69 6e 20 20 65 e $, msg-join e
7640: 6e 64 2d 77 69 74 68 0a 20 20 20 20 45 4c 53 45 nd-with. ELSE
7650: 20 20 32 64 72 6f 70 20 20 54 48 45 4e 20 3b 0a 2drop THEN ;.
7660: 0a 3a 20 6c 65 61 76 65 2c 20 28 20 2d 2d 20 29 .: leave, ( -- )
7670: 0a 20 20 20 20 5b 3a 20 6d 73 67 2d 6c 65 61 76 . [: msg-leav
7680: 65 0a 20 20 20 20 20 20 3c 6d 73 67 20 6d 73 67 e. <msg msg
7690: 2d 73 74 61 72 74 20 22 6c 65 66 74 22 20 24 2c -start "left" $,
76a0: 20 6d 73 67 2d 61 63 74 69 6f 6e 20 6d 73 67 2d msg-action msg-
76b0: 6f 74 72 3e 20 3b 5d 20 5b 6d 73 67 2c 5d 20 3b otr> ;] [msg,] ;
76c0: 0a 0a 3a 20 73 69 6c 65 6e 74 2d 6c 65 61 76 65 ..: silent-leave
76d0: 2c 20 28 20 2d 2d 20 29 0a 20 20 20 20 5b 27 5d , ( -- ). [']
76e0: 20 6d 73 67 2d 6c 65 61 76 65 20 5b 6d 73 67 2c msg-leave [msg,
76f0: 5d 20 3b 0a 0a 3a 20 6c 65 66 74 2c 20 28 20 61 ] ;..: left, ( a
7700: 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6b ddr u -- ). k
7710: 65 79 7c 20 24 2c 20 6d 73 67 2d 73 69 67 6e 61 ey| $, msg-signa
7720: 6c 20 22 6c 65 66 74 20 28 74 69 6d 65 6f 75 74 l "left (timeout
7730: 29 22 20 24 2c 20 6d 73 67 2d 61 63 74 69 6f 6e )" $, msg-action
7740: 20 3b 0a 70 72 65 76 69 6f 75 73 0a 0a 3a 20 73 ;.previous..: s
7750: 65 6e 64 2d 6a 6f 69 6e 20 28 20 2d 2d 20 29 0a end-join ( -- ).
7760: 20 20 20 20 6e 65 74 32 6f 2d 63 6f 64 65 20 65 net2o-code e
7770: 78 70 65 63 74 2d 6d 73 67 20 6a 6f 69 6e 2c 0a xpect-msg join,.
7780: 20 20 20 20 28 20 63 6f 6f 6b 69 65 2b 72 65 71 ( cookie+req
7790: 75 65 73 74 20 29 20 65 6e 64 2d 63 6f 64 65 7c uest ) end-code|
77a0: 20 3b 0a 0a 3a 20 73 69 6c 65 6e 74 2d 6a 6f 69 ;..: silent-joi
77b0: 6e 20 28 20 2d 2d 20 29 0a 20 20 20 20 6e 65 74 n ( -- ). net
77c0: 32 6f 2d 63 6f 64 65 20 65 78 70 65 63 74 2d 6d 2o-code expect-m
77d0: 73 67 20 73 69 6c 65 6e 74 2d 6a 6f 69 6e 2c 0a sg silent-join,.
77e0: 20 20 20 20 65 6e 64 2d 63 6f 64 65 20 3b 0a 0a end-code ;..
77f0: 3a 20 73 65 6e 64 2d 6c 65 61 76 65 20 28 20 2d : send-leave ( -
7800: 2d 20 29 0a 20 20 20 20 63 6f 6e 6e 65 63 74 69 - ). connecti
7810: 6f 6e 20 2e 64 61 74 61 2d 72 6d 61 70 20 49 46 on .data-rmap IF
7820: 20 20 6e 65 74 32 6f 2d 63 6f 64 65 20 65 78 70 net2o-code exp
7830: 65 63 74 2d 6d 73 67 20 6c 65 61 76 65 2c 20 65 ect-msg leave, e
7840: 6e 64 2d 63 6f 64 65 7c 20 20 54 48 45 4e 20 3b nd-code| THEN ;
7850: 0a 3a 20 73 65 6e 64 2d 73 69 6c 65 6e 74 2d 6c .: send-silent-l
7860: 65 61 76 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 eave ( -- ).
7870: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2e 64 61 74 61 connection .data
7880: 2d 72 6d 61 70 20 49 46 20 20 6e 65 74 32 6f 2d -rmap IF net2o-
7890: 63 6f 64 65 20 65 78 70 65 63 74 2d 6d 73 67 20 code expect-msg
78a0: 73 69 6c 65 6e 74 2d 6c 65 61 76 65 2c 20 65 6e silent-leave, en
78b0: 64 2d 63 6f 64 65 7c 20 20 54 48 45 4e 20 3b 0a d-code| THEN ;.
78c0: 0a 3a 20 5b 67 72 6f 75 70 5d 20 28 20 78 74 20 .: [group] ( xt
78d0: 2d 2d 20 66 6c 61 67 20 29 0a 20 20 20 20 6d 73 -- flag ). ms
78e0: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 70 g-group-o .msg:p
78f0: 65 65 72 73 5b 5d 20 24 40 6c 65 6e 20 49 46 0a eers[] $@len IF.
7900: 09 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 65 78 .msg-group-o .ex
7910: 65 63 75 74 65 20 74 72 75 65 0a 20 20 20 20 45 ecute true. E
7920: 4c 53 45 0a 09 30 20 2e 65 78 65 63 75 74 65 20 LSE..0 .execute
7930: 66 61 6c 73 65 0a 20 20 20 20 54 48 45 4e 20 3b false. THEN ;
7940: 0a 3a 20 2e 63 68 61 74 20 28 20 61 64 64 72 20 .: .chat ( addr
7950: 75 20 2d 2d 20 29 0a 20 20 20 20 5b 3a 20 6c 61 u -- ). [: la
7960: 73 74 23 20 3e 72 20 6f 20 49 46 20 20 32 64 75 st# >r o IF 2du
7970: 70 20 64 6f 2d 6d 73 67 2d 6e 65 73 74 73 69 67 p do-msg-nestsig
7980: 0a 20 20 20 20 20 20 45 4c 53 45 20 20 32 64 75 . ELSE 2du
7990: 70 20 64 69 73 70 6c 61 79 2d 6f 6e 65 2d 6d 73 p display-one-ms
79a0: 67 20 20 54 48 45 4e 20 20 72 3e 20 74 6f 20 6c g THEN r> to l
79b0: 61 73 74 23 0a 20 20 20 20 20 20 30 20 2e 61 76 ast#. 0 .av
79c0: 61 6c 61 6e 63 68 65 2d 6d 73 67 20 3b 5d 20 5b alanche-msg ;] [
79d0: 67 72 6f 75 70 5d 20 64 72 6f 70 20 6e 6f 74 69 group] drop noti
79e0: 66 79 2d 20 3b 0a 0a 5c 20 63 68 61 74 20 6d 65 fy- ;..\ chat me
79f0: 73 73 61 67 65 2c 20 74 65 78 74 20 6f 6e 6c 79 ssage, text only
7a00: 0a 0a 3a 20 6d 73 67 2d 74 64 69 73 70 6c 61 79 ..: msg-tdisplay
7a10: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 ( addr u -- ).
7a20: 20 20 20 32 64 75 70 20 32 20 2d 20 2b 20 63 40 2dup 2 - + c@
7a30: 20 24 38 30 20 61 6e 64 20 49 46 20 20 6d 73 67 $80 and IF msg
7a40: 2d 64 65 63 2d 73 69 67 3f 20 49 46 0a 09 20 20 -dec-sig? IF..
7a50: 20 20 32 64 72 6f 70 20 3c 65 72 72 3e 20 2e 22 2drop <err> ."
7a60: 20 55 6e 64 65 63 72 79 70 74 61 62 6c 65 20 6d Undecryptable m
7a70: 65 73 73 61 67 65 22 20 3c 64 65 66 61 75 6c 74 essage" <default
7a80: 3e 20 63 72 20 20 45 58 49 54 0a 09 54 48 45 4e > cr EXIT..THEN
7a90: 20 20 3c 69 6e 66 6f 3e 20 20 54 48 45 4e 0a 20 <info> THEN.
7aa0: 20 20 20 73 69 67 70 6b 73 69 7a 65 23 20 2d 20 sigpksize# -
7ab0: 32 64 75 70 20 2b 20 73 69 67 70 6b 73 69 7a 65 2dup + sigpksize
7ac0: 23 20 3e 24 20 20 63 2d 73 74 61 74 65 20 6f 66 # >$ c-state of
7ad0: 66 0a 20 20 20 20 6e 65 73 74 2d 63 6d 64 2d 6c f. nest-cmd-l
7ae0: 6f 6f 70 20 6d 73 67 3a 65 6e 64 20 3c 64 65 66 oop msg:end <def
7af0: 61 75 6c 74 3e 20 3b 0a 27 20 6d 73 67 2d 74 64 ault> ;.' msg-td
7b00: 69 73 70 6c 61 79 20 6d 73 67 2d 63 6c 61 73 73 isplay msg-class
7b10: 20 69 73 20 6d 73 67 3a 64 69 73 70 6c 61 79 0a is msg:display.
7b20: 27 20 6d 73 67 2d 74 64 69 73 70 6c 61 79 20 6d ' msg-tdisplay m
7b30: 73 67 2d 6e 6f 74 69 66 79 2d 63 6c 61 73 73 20 sg-notify-class
7b40: 69 73 20 6d 73 67 3a 64 69 73 70 6c 61 79 0a 3a is msg:display.:
7b50: 20 3f 73 65 61 72 63 68 2d 6c 6f 63 6b 20 28 20 ?search-lock (
7b60: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
7b70: 42 45 47 49 4e 20 20 64 75 70 20 20 57 48 49 4c BEGIN dup WHIL
7b80: 45 20 20 63 65 6c 6c 2d 20 32 64 75 70 20 2b 20 E cell- 2dup +
7b90: 24 40 20 73 69 67 70 6b 73 69 7a 65 23 20 2d 20 $@ sigpksize# -
7ba0: 31 2d 20 2b 20 63 40 20 24 32 45 20 3d 20 49 46 1- + c@ $2E = IF
7bb0: 0a 09 09 32 64 75 70 20 2b 20 24 40 20 5b 27 5d ...2dup + $@ [']
7bc0: 20 6d 73 67 3a 64 69 73 70 6c 61 79 20 63 61 74 msg:display cat
7bd0: 63 68 20 49 46 20 20 32 64 72 6f 70 20 20 54 48 ch IF 2drop TH
7be0: 45 4e 0a 09 09 6d 73 67 2d 67 72 6f 75 70 2d 6f EN...msg-group-o
7bf0: 20 2e 6d 73 67 3a 6b 65 79 73 5b 5d 20 24 5b 5d .msg:keys[] $[]
7c00: 23 20 49 46 20 20 64 72 6f 70 20 30 20 20 54 48 # IF drop 0 TH
7c10: 45 4e 0a 09 20 20 20 20 54 48 45 4e 0a 20 20 20 EN.. THEN.
7c20: 20 52 45 50 45 41 54 20 20 32 64 72 6f 70 20 3b REPEAT 2drop ;
7c30: 0a 3a 20 6d 73 67 2d 74 72 65 64 69 73 70 6c 61 .: msg-tredispla
7c40: 79 20 28 20 6e 20 2d 2d 20 29 0a 20 20 20 20 72 y ( n -- ). r
7c50: 65 73 65 74 2d 74 69 6d 65 0a 20 20 20 20 6d 73 eset-time. ms
7c60: 67 2d 67 72 6f 75 70 2d 6f 20 3e 6f 20 6d 73 67 g-group-o >o msg
7c70: 3a 3f 6f 74 72 20 6d 73 67 3a 2d 6f 74 72 20 6f :?otr msg:-otr o
7c80: 3e 20 3e 72 0a 20 20 20 20 5b 3a 20 20 63 65 6c > >r. [: cel
7c90: 6c 73 20 3e 72 20 6d 73 67 2d 6c 6f 67 40 0a 09 ls >r msg-log@..
7ca0: 7b 20 6c 6f 67 20 75 20 7d 20 75 20 72 3e 20 2d { log u } u r> -
7cb0: 20 30 20 6d 61 78 20 7b 20 75 27 20 7d 20 20 6c 0 max { u' } l
7cc0: 6f 67 20 75 27 20 3f 73 65 61 72 63 68 2d 6c 6f og u' ?search-lo
7cd0: 63 6b 0a 09 6c 6f 67 20 75 20 75 27 20 2f 73 74 ck..log u u' /st
7ce0: 72 69 6e 67 20 62 6f 75 6e 64 73 20 3f 44 4f 0a ring bounds ?DO.
7cf0: 09 20 20 20 20 49 20 6c 6f 67 20 2d 20 63 65 6c . I log - cel
7d00: 6c 2f 20 74 6f 20 6c 6f 67 23 0a 09 20 20 20 20 l/ to log#..
7d10: 49 20 24 40 20 7b 20 64 3a 20 6d 73 67 74 20 7d I $@ { d: msgt }
7d20: 0a 09 20 20 20 20 6d 73 67 74 20 5b 27 5d 20 6d .. msgt ['] m
7d30: 73 67 3a 64 69 73 70 6c 61 79 20 63 61 74 63 68 sg:display catch
7d40: 20 49 46 20 20 2e 22 20 69 6e 76 61 6c 69 64 20 IF ." invalid
7d50: 65 6e 74 72 79 22 20 63 72 0a 09 09 32 64 72 6f entry" cr...2dro
7d60: 70 20 20 54 48 45 4e 0a 09 63 65 6c 6c 20 2b 4c p THEN..cell +L
7d70: 4f 4f 50 0a 09 6c 6f 67 20 66 72 65 65 20 74 68 OOP..log free th
7d80: 72 6f 77 20 3b 5d 20 63 61 74 63 68 0a 20 20 20 row ;] catch.
7d90: 20 72 3e 20 49 46 20 20 6d 73 67 2d 67 72 6f 75 r> IF msg-grou
7da0: 70 2d 6f 20 2e 6d 73 67 3a 2b 6f 74 72 20 20 54 p-o .msg:+otr T
7db0: 48 45 4e 20 20 74 68 72 6f 77 20 3b 0a 27 20 6d HEN throw ;.' m
7dc0: 73 67 2d 74 72 65 64 69 73 70 6c 61 79 20 6d 73 sg-tredisplay ms
7dd0: 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 72 g-class is msg:r
7de0: 65 64 69 73 70 6c 61 79 0a 0a 6d 73 67 2d 63 6c edisplay..msg-cl
7df0: 61 73 73 20 63 6c 61 73 73 0a 65 6e 64 2d 63 6c ass class.end-cl
7e00: 61 73 73 20 74 65 78 74 6d 73 67 2d 63 6c 61 73 ass textmsg-clas
7e10: 73 0a 0a 27 20 32 64 72 6f 70 20 74 65 78 74 6d s..' 2drop textm
7e20: 73 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a sg-class is msg:
7e30: 73 74 61 72 74 0a 3a 6e 6f 6e 61 6d 65 20 27 23 start.:noname '#
7e40: 27 20 65 6d 69 74 20 74 79 70 65 20 3b 20 74 65 ' emit type ; te
7e50: 78 74 6d 73 67 2d 63 6c 61 73 73 20 69 73 20 6d xtmsg-class is m
7e60: 73 67 3a 74 61 67 0a 3a 6e 6f 6e 61 6d 65 20 27 sg:tag.:noname '
7e70: 40 27 20 65 6d 69 74 20 2e 73 69 6d 70 6c 65 2d @' emit .simple-
7e80: 69 64 20 3b 20 74 65 78 74 6d 73 67 2d 63 6c 61 id ; textmsg-cla
7e90: 73 73 20 69 73 20 6d 73 67 3a 73 69 67 6e 61 6c ss is msg:signal
7ea0: 0a 27 20 32 64 72 6f 70 20 74 65 78 74 6d 73 67 .' 2drop textmsg
7eb0: 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 72 65 -class is msg:re
7ec0: 0a 27 20 32 64 72 6f 70 20 74 65 78 74 6d 73 67 .' 2drop textmsg
7ed0: 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 63 68 -class is msg:ch
7ee0: 61 69 6e 0a 27 20 74 79 70 65 20 74 65 78 74 6d ain.' type textm
7ef0: 73 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a sg-class is msg:
7f00: 74 65 78 74 0a 3a 6e 6f 6e 61 6d 65 20 64 72 6f text.:noname dro
7f10: 70 20 32 64 72 6f 70 20 3b 20 74 65 78 74 6d 73 p 2drop ; textms
7f20: 67 2d 63 6c 61 73 73 20 69 73 20 6d 73 67 3a 6f g-class is msg:o
7f30: 62 6a 65 63 74 0a 3a 6e 6f 6e 61 6d 65 20 2e 22 bject.:noname ."
7f40: 20 2f 6d 65 20 22 20 74 79 70 65 20 3b 20 74 65 /me " type ; te
7f50: 78 74 6d 73 67 2d 63 6c 61 73 73 20 69 73 20 6d xtmsg-class is m
7f60: 73 67 3a 61 63 74 69 6f 6e 0a 3a 6e 6f 6e 61 6d sg:action.:nonam
7f70: 65 20 2e 22 20 2f 68 65 72 65 20 22 20 32 64 72 e ." /here " 2dr
7f80: 6f 70 20 3b 20 74 65 78 74 6d 73 67 2d 63 6c 61 op ; textmsg-cla
7f90: 73 73 20 69 73 20 6d 73 67 3a 63 6f 6f 72 64 0a ss is msg:coord.
7fa0: 27 20 6e 6f 6f 70 20 74 65 78 74 6d 73 67 2d 63 ' noop textmsg-c
7fb0: 6c 61 73 73 20 69 73 20 6d 73 67 3a 65 6e 64 0a lass is msg:end.
7fc0: 0a 74 65 78 74 6d 73 67 2d 63 6c 61 73 73 20 27 .textmsg-class '
7fd0: 20 6e 65 77 20 73 74 61 74 69 63 2d 61 20 77 69 new static-a wi
7fe0: 74 68 2d 61 6c 6c 6f 63 61 74 65 72 20 43 6f 6e th-allocater Con
7ff0: 73 74 61 6e 74 20 74 65 78 74 6d 73 67 2d 6f 0a stant textmsg-o.
8000: 6d 73 67 2d 6e 6f 74 69 66 79 2d 6f 20 3e 6f 20 msg-notify-o >o
8010: 6d 73 67 2d 74 61 62 6c 65 20 40 20 74 6f 6b 65 msg-table @ toke
8020: 6e 2d 74 61 62 6c 65 20 21 20 6f 3e 0a 74 65 78 n-table ! o>.tex
8030: 74 6d 73 67 2d 6f 20 3e 6f 20 6d 73 67 2d 74 61 tmsg-o >o msg-ta
8040: 62 6c 65 20 40 20 74 6f 6b 65 6e 2d 74 61 62 6c ble @ token-tabl
8050: 65 20 21 20 6f 3e 0a 0a 5c 20 63 68 61 74 20 68 e ! o>..\ chat h
8060: 69 73 74 6f 72 79 20 62 72 6f 77 73 69 6e 67 0a istory browsing.
8070: 0a 36 34 56 61 72 69 61 62 6c 65 20 6c 69 6e 65 .64Variable line
8080: 2d 64 61 74 65 20 36 34 23 2d 31 20 6c 69 6e 65 -date 64#-1 line
8090: 2d 64 61 74 65 20 36 34 21 0a 56 61 72 69 61 62 -date 64!.Variab
80a0: 6c 65 20 24 6c 61 73 74 6c 69 6e 65 0a 0a 3a 20 le $lastline..:
80b0: 21 64 61 74 65 20 28 20 61 64 64 72 20 75 20 2d !date ( addr u -
80c0: 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 32 - addr u ). 2
80d0: 64 75 70 20 2b 20 73 69 67 73 69 7a 65 23 20 2d dup + sigsize# -
80e0: 20 6c 65 2d 36 34 40 20 6c 69 6e 65 2d 64 61 74 le-64@ line-dat
80f0: 65 20 36 34 21 20 3b 0a 3a 20 66 69 6e 64 2d 70 e 64! ;.: find-p
8100: 72 65 76 2d 63 68 61 74 6c 69 6e 65 20 7b 20 6d rev-chatline { m
8110: 61 78 6c 65 6e 20 61 64 64 72 20 2d 2d 20 6d 61 axlen addr -- ma
8120: 78 20 73 70 61 6e 20 61 64 64 72 20 73 70 61 6e x span addr span
8130: 20 7d 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 }. msg-group
8140: 24 20 24 40 20 3e 67 72 6f 75 70 0a 20 20 20 20 $ $@ >group.
8150: 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 msg-group-o .msg
8160: 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 20 30 3d 20 49 :log[] $[]# 0= I
8170: 46 20 20 6d 61 78 6c 65 6e 20 30 20 61 64 64 72 F maxlen 0 addr
8180: 20 6f 76 65 72 20 20 45 58 49 54 20 20 54 48 45 over EXIT THE
8190: 4e 0a 20 20 20 20 6c 69 6e 65 2d 64 61 74 65 20 N. line-date
81a0: 36 34 40 20 64 61 74 65 3e 69 27 0a 20 20 20 20 64@ date>i'.
81b0: 42 45 47 49 4e 20 20 31 2d 20 64 75 70 20 30 3e BEGIN 1- dup 0>
81c0: 3d 20 57 48 49 4c 45 20 20 64 75 70 20 6d 73 67 = WHILE dup msg
81d0: 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f -group-o .msg:lo
81e0: 67 5b 5d 20 24 5b 5d 40 0a 09 64 75 70 20 73 69 g[] $[]@..dup si
81f0: 67 70 6b 73 69 7a 65 23 20 2d 20 2f 73 74 72 69 gpksize# - /stri
8200: 6e 67 20 6b 65 79 7c 20 70 6b 40 20 6b 65 79 7c ng key| pk@ key|
8210: 20 73 74 72 3d 20 20 55 4e 54 49 4c 20 20 54 48 str= UNTIL TH
8220: 45 4e 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 EN. msg-group
8230: 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b -o .msg:log[] $[
8240: 5d 40 20 64 75 70 20 30 3d 20 49 46 20 20 6e 69 ]@ dup 0= IF ni
8250: 70 0a 20 20 20 20 45 4c 53 45 20 20 21 64 61 74 p. ELSE !dat
8260: 65 20 5b 27 5d 20 6d 73 67 3a 64 69 73 70 6c 61 e ['] msg:displa
8270: 79 20 74 65 78 74 6d 73 67 2d 6f 20 2e 24 74 6d y textmsg-o .$tm
8280: 70 20 0a 09 64 75 70 20 6d 61 78 6c 65 6e 20 75 p ..dup maxlen u
8290: 3e 20 49 46 20 20 64 75 70 20 3e 72 20 6d 61 78 > IF dup >r max
82a0: 6c 65 6e 20 30 20 61 64 64 72 20 6f 76 65 72 20 len 0 addr over
82b0: 72 3e 20 67 72 6f 77 2d 74 69 62 0a 09 20 20 20 r> grow-tib..
82c0: 20 32 64 72 6f 70 20 74 6f 20 61 64 64 72 20 64 2drop to addr d
82d0: 72 6f 70 20 74 6f 20 6d 61 78 6c 65 6e 20 20 54 rop to maxlen T
82e0: 48 45 4e 0a 09 74 75 63 6b 20 61 64 64 72 20 6d HEN..tuck addr m
82f0: 61 78 6c 65 6e 20 73 6d 6f 76 65 0a 20 20 20 20 axlen smove.
8300: 54 48 45 4e 0a 20 20 20 20 6d 61 78 6c 65 6e 20 THEN. maxlen
8310: 73 77 61 70 20 61 64 64 72 20 6f 76 65 72 20 3b swap addr over ;
8320: 0a 3a 20 66 69 6e 64 2d 6e 65 78 74 2d 63 68 61 .: find-next-cha
8330: 74 6c 69 6e 65 20 7b 20 6d 61 78 6c 65 6e 20 61 tline { maxlen a
8340: 64 64 72 20 2d 2d 20 6d 61 78 20 73 70 61 6e 20 ddr -- max span
8350: 61 64 64 72 20 73 70 61 6e 20 7d 0a 20 20 20 20 addr span }.
8360: 6d 73 67 2d 67 72 6f 75 70 24 20 24 40 20 3e 67 msg-group$ $@ >g
8370: 72 6f 75 70 0a 20 20 20 20 6c 69 6e 65 2d 64 61 roup. line-da
8380: 74 65 20 36 34 40 20 64 61 74 65 3e 69 0a 20 20 te 64@ date>i.
8390: 20 20 42 45 47 49 4e 20 20 31 2b 20 64 75 70 20 BEGIN 1+ dup
83a0: 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 msg-group-o .msg
83b0: 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 20 75 3c 20 57 :log[] $[]# u< W
83c0: 48 49 4c 45 20 20 64 75 70 20 6d 73 67 2d 67 72 HILE dup msg-gr
83d0: 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d oup-o .msg:log[]
83e0: 20 24 5b 5d 40 0a 09 64 75 70 20 73 69 67 70 6b $[]@..dup sigpk
83f0: 73 69 7a 65 23 20 2d 20 2f 73 74 72 69 6e 67 20 size# - /string
8400: 6b 65 79 7c 20 70 6b 40 20 6b 65 79 7c 20 73 74 key| pk@ key| st
8410: 72 3d 20 20 55 4e 54 49 4c 20 20 54 48 45 4e 0a r= UNTIL THEN.
8420: 20 20 20 20 64 75 70 20 6d 73 67 2d 67 72 6f 75 dup msg-grou
8430: 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 p-o .msg:log[] $
8440: 5b 5d 23 20 75 3e 3d 0a 20 20 20 20 49 46 20 20 []# u>=. IF
8450: 20 20 64 72 6f 70 20 24 6c 61 73 74 6c 69 6e 65 drop $lastline
8460: 20 24 40 20 20 36 34 23 2d 31 20 6c 69 6e 65 2d $@ 64#-1 line-
8470: 64 61 74 65 20 36 34 21 0a 20 20 20 20 45 4c 53 date 64!. ELS
8480: 45 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e E msg-group-o .
8490: 6d 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 40 20 21 msg:log[] $[]@ !
84a0: 64 61 74 65 20 5b 27 5d 20 6d 73 67 3a 64 69 73 date ['] msg:dis
84b0: 70 6c 61 79 20 74 65 78 74 6d 73 67 2d 6f 20 2e play textmsg-o .
84c0: 24 74 6d 70 20 20 54 48 45 4e 0a 20 20 20 20 64 $tmp THEN. d
84d0: 75 70 20 6d 61 78 6c 65 6e 20 75 3e 20 49 46 20 up maxlen u> IF
84e0: 20 64 75 70 20 3e 72 20 6d 61 78 6c 65 6e 20 30 dup >r maxlen 0
84f0: 20 61 64 64 72 20 6f 76 65 72 20 72 3e 20 67 72 addr over r> gr
8500: 6f 77 2d 74 69 62 0a 09 32 64 72 6f 70 20 74 6f ow-tib..2drop to
8510: 20 61 64 64 72 20 64 72 6f 70 20 74 6f 20 6d 61 addr drop to ma
8520: 78 6c 65 6e 20 20 54 48 45 4e 0a 20 20 20 20 74 xlen THEN. t
8530: 75 63 6b 20 61 64 64 72 20 6d 61 78 6c 65 6e 20 uck addr maxlen
8540: 73 6d 6f 76 65 0a 20 20 20 20 6d 61 78 6c 65 6e smove. maxlen
8550: 20 73 77 61 70 20 61 64 64 72 20 6f 76 65 72 20 swap addr over
8560: 3b 0a 0a 3a 20 63 68 61 74 2d 70 72 65 76 2d 6c ;..: chat-prev-l
8570: 69 6e 65 20 20 28 20 6d 61 78 20 73 70 61 6e 20 ine ( max span
8580: 61 64 64 72 20 70 6f 73 31 20 2d 2d 20 6d 61 78 addr pos1 -- max
8590: 20 73 70 61 6e 20 61 64 64 72 20 70 6f 73 32 20 span addr pos2
85a0: 66 61 6c 73 65 20 29 0a 20 20 20 20 6c 69 6e 65 false ). line
85b0: 2d 64 61 74 65 20 36 34 40 20 36 34 23 2d 31 20 -date 64@ 64#-1
85c0: 36 34 3d 20 49 46 0a 09 3e 72 20 32 64 75 70 20 64= IF..>r 2dup
85d0: 73 77 61 70 20 24 6c 61 73 74 6c 69 6e 65 20 24 swap $lastline $
85e0: 21 20 72 3e 20 20 54 48 45 4e 0a 20 20 20 20 63 ! r> THEN. c
85f0: 6c 65 61 72 2d 6c 69 6e 65 20 66 69 6e 64 2d 70 lear-line find-p
8600: 72 65 76 2d 63 68 61 74 6c 69 6e 65 0a 20 20 20 rev-chatline.
8610: 20 65 64 69 74 2d 75 70 64 61 74 65 20 66 61 6c edit-update fal
8620: 73 65 20 3b 0a 3a 20 63 68 61 74 2d 6e 65 78 74 se ;.: chat-next
8630: 2d 6c 69 6e 65 20 20 28 20 6d 61 78 20 73 70 61 -line ( max spa
8640: 6e 20 61 64 64 72 20 70 6f 73 31 20 2d 2d 20 6d n addr pos1 -- m
8650: 61 78 20 73 70 61 6e 20 61 64 64 72 20 70 6f 73 ax span addr pos
8660: 32 20 66 61 6c 73 65 20 29 0a 20 20 20 20 6c 69 2 false ). li
8670: 6e 65 2d 64 61 74 65 20 36 34 40 20 36 34 23 2d ne-date 64@ 64#-
8680: 31 20 36 34 3d 20 49 46 20 20 66 61 6c 73 65 20 1 64= IF false
8690: 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 EXIT THEN.
86a0: 63 6c 65 61 72 2d 6c 69 6e 65 20 66 69 6e 64 2d clear-line find-
86b0: 6e 65 78 74 2d 63 68 61 74 6c 69 6e 65 0a 20 20 next-chatline.
86c0: 20 20 65 64 69 74 2d 75 70 64 61 74 65 20 66 61 edit-update fa
86d0: 6c 73 65 20 3b 0a 3a 20 63 68 61 74 2d 65 6e 74 lse ;.: chat-ent
86e0: 65 72 20 28 20 6d 61 78 20 73 70 61 6e 20 61 64 er ( max span ad
86f0: 64 72 20 70 6f 73 31 20 2d 2d 20 6d 61 78 20 73 dr pos1 -- max s
8700: 70 61 6e 20 61 64 64 72 20 70 6f 73 32 20 74 72 pan addr pos2 tr
8710: 75 65 20 29 0a 20 20 20 20 64 72 6f 70 20 6f 76 ue ). drop ov
8720: 65 72 20 65 64 69 74 2d 75 70 64 61 74 65 20 74 er edit-update t
8730: 72 75 65 20 36 34 23 2d 31 20 6c 69 6e 65 2d 64 rue 64#-1 line-d
8740: 61 74 65 20 36 34 21 20 3b 0a 0a 65 64 69 74 2d ate 64! ;..edit-
8750: 74 65 72 6d 69 6e 61 6c 2d 63 20 63 6c 61 73 73 terminal-c class
8760: 0a 65 6e 64 2d 63 6c 61 73 73 20 63 68 61 74 2d .end-class chat-
8770: 74 65 72 6d 69 6e 61 6c 2d 63 0a 63 68 61 74 2d terminal-c.chat-
8780: 74 65 72 6d 69 6e 61 6c 2d 63 20 27 20 6e 65 77 terminal-c ' new
8790: 20 73 74 61 74 69 63 2d 61 20 77 69 74 68 2d 61 static-a with-a
87a0: 6c 6c 6f 63 61 74 65 72 20 43 6f 6e 73 74 61 6e llocater Constan
87b0: 74 20 63 68 61 74 2d 74 65 72 6d 69 6e 61 6c 0a t chat-terminal.
87c0: 0a 62 6c 20 63 65 6c 6c 73 20 62 75 66 66 65 72 .bl cells buffer
87d0: 3a 20 63 68 61 74 2d 63 74 72 6c 6b 65 79 73 0a : chat-ctrlkeys.
87e0: 78 63 68 61 72 2d 63 74 72 6c 6b 65 79 73 20 63 xchar-ctrlkeys c
87f0: 68 61 74 2d 63 74 72 6c 6b 65 79 73 20 62 6c 20 hat-ctrlkeys bl
8800: 63 65 6c 6c 73 20 6d 6f 76 65 0a 0a 63 68 61 74 cells move..chat
8810: 2d 74 65 72 6d 69 6e 61 6c 20 65 64 69 74 2d 6f -terminal edit-o
8820: 75 74 20 21 0a 0a 27 20 63 68 61 74 2d 63 74 72 ut !..' chat-ctr
8830: 6c 6b 65 79 73 20 69 73 20 63 74 72 6c 6b 65 79 lkeys is ctrlkey
8840: 73 0a 0a 27 20 63 68 61 74 2d 6e 65 78 74 2d 6c s..' chat-next-l
8850: 69 6e 65 20 63 74 72 6c 20 4e 20 62 69 6e 64 6b ine ctrl N bindk
8860: 65 79 0a 27 20 63 68 61 74 2d 70 72 65 76 2d 6c ey.' chat-prev-l
8870: 69 6e 65 20 63 74 72 6c 20 50 20 62 69 6e 64 6b ine ctrl P bindk
8880: 65 79 0a 27 20 63 68 61 74 2d 65 6e 74 65 72 20 ey.' chat-enter
8890: 20 20 20 20 23 6c 66 20 20 20 20 62 69 6e 64 6b #lf bindk
88a0: 65 79 0a 27 20 63 68 61 74 2d 65 6e 74 65 72 20 ey.' chat-enter
88b0: 20 20 20 20 23 63 72 20 20 20 20 62 69 6e 64 6b #cr bindk
88c0: 65 79 0a 5c 20 3a 6e 6f 6e 61 6d 65 20 23 74 61 ey.\ :noname #ta
88d0: 62 20 28 78 69 6e 73 29 20 30 20 3b 20 23 74 61 b (xins) 0 ; #ta
88e0: 62 20 20 20 62 69 6e 64 6b 65 79 0a 5b 49 46 44 b bindkey.[IFD
88f0: 45 46 5d 20 65 62 69 6e 64 6b 65 79 0a 20 20 20 EF] ebindkey.
8900: 20 6b 65 79 63 6f 64 65 2d 6c 69 6d 69 74 20 6b keycode-limit k
8910: 65 79 63 6f 64 65 2d 73 74 61 72 74 20 2d 20 63 eycode-start - c
8920: 65 6c 6c 73 20 62 75 66 66 65 72 3a 20 63 68 61 ells buffer: cha
8930: 74 2d 65 6b 65 79 73 0a 20 20 20 20 73 74 64 2d t-ekeys. std-
8940: 65 6b 65 79 73 20 63 68 61 74 2d 65 6b 65 79 73 ekeys chat-ekeys
8950: 20 6b 65 79 63 6f 64 65 2d 6c 69 6d 69 74 20 6b keycode-limit k
8960: 65 79 63 6f 64 65 2d 73 74 61 72 74 20 2d 20 63 eycode-start - c
8970: 65 6c 6c 73 20 6d 6f 76 65 0a 20 20 20 20 0a 20 ells move. .
8980: 20 20 20 27 20 63 68 61 74 2d 65 6b 65 79 73 20 ' chat-ekeys
8990: 69 73 20 65 6b 65 79 73 0a 20 20 20 20 0a 20 20 is ekeys. .
89a0: 20 20 27 20 63 68 61 74 2d 6e 65 78 74 2d 6c 69 ' chat-next-li
89b0: 6e 65 20 6b 2d 64 6f 77 6e 20 20 65 62 69 6e 64 ne k-down ebind
89c0: 6b 65 79 0a 20 20 20 20 27 20 63 68 61 74 2d 70 key. ' chat-p
89d0: 72 65 76 2d 6c 69 6e 65 20 6b 2d 75 70 20 20 20 rev-line k-up
89e0: 20 65 62 69 6e 64 6b 65 79 0a 20 20 20 20 27 20 ebindkey. '
89f0: 63 68 61 74 2d 6e 65 78 74 2d 6c 69 6e 65 20 6b chat-next-line k
8a00: 2d 6e 65 78 74 20 20 65 62 69 6e 64 6b 65 79 0a -next ebindkey.
8a10: 20 20 20 20 27 20 63 68 61 74 2d 70 72 65 76 2d ' chat-prev-
8a20: 6c 69 6e 65 20 6b 2d 70 72 69 6f 72 20 65 62 69 line k-prior ebi
8a30: 6e 64 6b 65 79 0a 5b 54 48 45 4e 5d 0a 0a 65 64 ndkey.[THEN]..ed
8a40: 69 74 2d 74 65 72 6d 69 6e 61 6c 20 65 64 69 74 it-terminal edit
8a50: 2d 6f 75 74 20 21 0a 0a 3a 20 63 68 61 74 2d 68 -out !..: chat-h
8a60: 69 73 74 6f 72 79 20 28 20 2d 2d 20 29 0a 20 20 istory ( -- ).
8a70: 20 20 63 68 61 74 2d 74 65 72 6d 69 6e 61 6c 20 chat-terminal
8a80: 65 64 69 74 2d 6f 75 74 20 21 20 3b 0a 0a 5c 20 edit-out ! ;..\
8a90: 63 68 61 74 20 6c 69 6e 65 20 65 64 69 74 6f 72 chat line editor
8aa0: 0a 0a 24 32 30 30 20 43 6f 6e 73 74 61 6e 74 20 ..$200 Constant
8ab0: 6d 61 78 6d 73 67 23 0a 0a 3a 20 67 65 74 2d 69 maxmsg#..: get-i
8ac0: 6e 70 75 74 2d 6c 69 6e 65 20 28 20 2d 2d 20 61 nput-line ( -- a
8ad0: 64 64 72 20 75 20 29 0a 20 20 20 20 42 45 47 49 ddr u ). BEGI
8ae0: 4e 20 20 70 61 64 20 6d 61 78 6d 73 67 23 20 5b N pad maxmsg# [
8af0: 27 5d 20 61 63 63 65 70 74 20 63 61 74 63 68 0a '] accept catch.
8b00: 09 64 75 70 20 64 75 70 20 2d 35 36 20 3d 20 73 .dup dup -56 = s
8b10: 77 61 70 20 2d 32 38 20 3d 20 6f 72 20 5c 20 71 wap -28 = or \ q
8b20: 75 69 74 20 6f 72 20 5e 63 20 74 6f 20 6c 65 61 uit or ^c to lea
8b30: 76 65 0a 09 49 46 20 20 20 20 64 72 6f 70 20 32 ve..IF drop 2
8b40: 64 72 6f 70 20 22 2f 62 79 65 22 0a 09 45 4c 53 drop "/bye"..ELS
8b50: 45 0a 09 20 20 20 20 64 75 70 20 30 3d 20 49 46 E.. dup 0= IF
8b60: 0a 09 09 64 72 6f 70 20 70 61 64 20 73 77 61 70 ...drop pad swap
8b70: 20 32 64 75 70 20 78 63 6c 65 61 72 0a 09 20 20 2dup xclear..
8b80: 20 20 45 4c 53 45 0a 09 09 44 6f 45 72 72 6f 72 ELSE...DoError
8b90: 20 64 72 6f 70 20 30 20 20 54 48 45 4e 0a 09 54 drop 0 THEN..T
8ba0: 48 45 4e 0a 09 64 75 70 20 30 3d 20 57 48 49 4c HEN..dup 0= WHIL
8bb0: 45 20 20 32 64 72 6f 70 20 20 52 45 50 45 41 54 E 2drop REPEAT
8bc0: 20 3b 0a 0a 5c 20 6a 6f 69 6e 69 6e 67 20 61 6e ;..\ joining an
8bd0: 64 20 6c 65 61 76 69 6e 67 0a 0a 3a 20 67 3f 6a d leaving..: g?j
8be0: 6f 69 6e 20 28 20 2d 2d 20 29 0a 20 20 20 20 6d oin ( -- ). m
8bf0: 73 67 2d 67 72 6f 75 70 24 20 24 40 6c 65 6e 20 sg-group$ $@len
8c00: 49 46 20 20 73 65 6e 64 2d 6a 6f 69 6e 20 2d 74 IF send-join -t
8c10: 69 6d 65 6f 75 74 20 20 54 48 45 4e 20 3b 0a 0a imeout THEN ;..
8c20: 3a 20 67 3f 6c 65 61 76 65 20 28 20 2d 2d 20 29 : g?leave ( -- )
8c30: 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 24 20 . msg-group$
8c40: 24 40 6c 65 6e 20 49 46 20 20 73 65 6e 64 2d 6c $@len IF send-l
8c50: 65 61 76 65 20 2d 74 69 6d 65 6f 75 74 20 20 54 eave -timeout T
8c60: 48 45 4e 20 3b 0a 0a 3a 20 67 72 65 65 74 20 28 HEN ;..: greet (
8c70: 20 2d 2d 20 29 0a 20 20 20 20 63 6f 6e 6e 65 63 -- ). connec
8c80: 74 69 6f 6e 20 2e 64 61 74 61 2d 72 6d 61 70 20 tion .data-rmap
8c90: 30 3d 20 3f 45 58 49 54 0a 20 20 20 20 6e 65 74 0= ?EXIT. net
8ca0: 32 6f 2d 63 6f 64 65 20 65 78 70 65 63 74 2d 6d 2o-code expect-m
8cb0: 73 67 0a 20 20 20 20 6c 6f 67 20 21 74 69 6d 65 sg. log !time
8cc0: 20 65 6e 64 2d 77 69 74 68 20 6a 6f 69 6e 2c 20 end-with join,
8cd0: 67 65 74 2d 69 70 20 65 6e 64 2d 63 6f 64 65 20 get-ip end-code
8ce0: 3b 0a 0a 3a 20 63 68 61 74 2d 65 6e 74 72 79 20 ;..: chat-entry
8cf0: 28 20 2d 2d 20 29 20 20 3f 2e 6e 65 74 32 6f 2f ( -- ) ?.net2o/
8d00: 63 68 61 74 73 20 20 77 6f 72 64 2d 61 72 67 73 chats word-args
8d10: 0a 20 20 20 20 3c 77 61 72 6e 3e 20 2e 22 20 54 . <warn> ." T
8d20: 79 70 65 20 63 74 72 6c 2d 44 20 6f 72 20 27 2f ype ctrl-D or '/
8d30: 62 79 65 27 20 61 73 20 73 69 6e 67 6c 65 20 69 bye' as single i
8d40: 74 65 6d 20 74 6f 20 71 75 69 74 22 20 3c 64 65 tem to quit" <de
8d50: 66 61 75 6c 74 3e 20 63 72 20 3b 0a 0a 61 6c 73 fault> cr ;..als
8d60: 6f 20 6e 65 74 32 6f 2d 62 61 73 65 0a 5c 20 63 o net2o-base.\ c
8d70: 68 61 69 6e 20 6d 65 73 73 61 67 65 73 20 74 6f hain messages to
8d80: 20 6f 6e 65 20 70 72 65 76 69 6f 75 73 20 6d 65 one previous me
8d90: 73 73 61 67 65 0a 3a 20 63 68 61 69 6e 2c 20 28 ssage.: chain, (
8da0: 20 6d 73 67 61 64 64 72 20 75 20 2d 2d 20 29 0a msgaddr u -- ).
8db0: 20 20 20 20 5b 3a 20 32 64 75 70 20 73 74 61 72 [: 2dup star
8dc0: 74 64 61 74 65 40 20 36 34 23 30 20 7b 20 36 34 tdate@ 64#0 { 64
8dd0: 5e 20 73 64 20 7d 20 73 64 20 6c 65 2d 36 34 21 ^ sd } sd le-64!
8de0: 20 20 73 64 20 31 20 36 34 73 20 66 6f 72 74 68 sd 1 64s forth
8df0: 3a 74 79 70 65 0a 09 63 3a 30 6b 65 79 20 73 69 :type..c:0key si
8e00: 67 6f 6e 6c 79 40 20 3e 68 61 73 68 20 68 61 73 gonly@ >hash has
8e10: 68 74 6d 70 20 68 61 73 68 23 31 32 38 20 66 6f htmp hash#128 fo
8e20: 72 74 68 3a 74 79 70 65 20 3b 5d 20 24 74 6d 70 rth:type ;] $tmp
8e30: 20 24 2c 20 6d 73 67 2d 63 68 61 69 6e 20 3b 0a $, msg-chain ;.
8e40: 0a 3a 20 28 73 65 6e 64 2d 61 76 61 6c 61 6e 63 .: (send-avalanc
8e50: 68 65 29 20 28 20 78 74 20 2d 2d 20 61 64 64 72 he) ( xt -- addr
8e60: 20 75 20 66 6c 61 67 20 29 0a 20 20 20 20 5b 3a u flag ). [:
8e70: 20 30 20 3e 6f 20 5b 3a 20 3c 6d 73 67 20 6d 73 0 >o [: <msg ms
8e80: 67 2d 73 74 61 72 74 20 65 78 65 63 75 74 65 20 g-start execute
8e90: 6d 73 67 3e 20 3b 5d 20 67 65 6e 2d 63 6d 64 24 msg> ;] gen-cmd$
8ea0: 20 6f 3e 0a 20 20 20 20 20 20 2b 6c 61 73 74 2d o>. +last-
8eb0: 73 69 67 6e 65 64 20 6d 73 67 2d 6c 6f 67 2c 20 signed msg-log,
8ec0: 3b 5d 20 5b 67 72 6f 75 70 5d 20 3b 0a 70 72 65 ;] [group] ;.pre
8ed0: 76 69 6f 75 73 0a 3a 20 73 65 6e 64 2d 61 76 61 vious.: send-ava
8ee0: 6c 61 6e 63 68 65 20 28 20 78 74 20 2d 2d 20 29 lanche ( xt -- )
8ef0: 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f . msg-group-o
8f00: 20 2e 6d 73 67 3a 3f 6f 74 72 20 49 46 20 20 6e .msg:?otr IF n
8f10: 6f 77 3e 6f 74 72 20 20 45 4c 53 45 20 20 6e 6f ow>otr ELSE no
8f20: 77 3e 6e 65 76 65 72 20 20 54 48 45 4e 0a 20 20 w>never THEN.
8f30: 20 20 28 73 65 6e 64 2d 61 76 61 6c 61 6e 63 68 (send-avalanch
8f40: 65 29 0a 20 20 20 20 3e 72 20 2e 63 68 61 74 20 e). >r .chat
8f50: 72 3e 20 30 3d 20 49 46 20 20 6d 73 67 2d 67 72 r> 0= IF msg-gr
8f60: 6f 75 70 2d 6f 20 2e 6d 73 67 3a 2e 6e 6f 62 6f oup-o .msg:.nobo
8f70: 64 79 20 20 54 48 45 4e 20 3b 0a 0a 5c 20 63 68 dy THEN ;..\ ch
8f80: 61 74 20 68 65 6c 70 65 72 20 77 6f 72 64 73 0a at helper words.
8f90: 0a 56 61 72 69 61 62 6c 65 20 63 68 61 74 2d 6b .Variable chat-k
8fa0: 65 79 73 0a 0a 3a 20 40 2f 20 28 20 61 64 64 72 eys..: @/ ( addr
8fb0: 20 75 20 2d 2d 20 61 64 64 72 31 20 75 31 20 61 u -- addr1 u1 a
8fc0: 64 64 72 32 20 75 32 20 29 20 27 40 27 20 24 73 ddr2 u2 ) '@' $s
8fd0: 70 6c 69 74 20 3b 0a 3a 20 40 2f 32 20 28 20 61 plit ;.: @/2 ( a
8fe0: 64 64 72 20 75 20 2d 2d 20 61 64 64 72 32 20 75 ddr u -- addr2 u
8ff0: 32 20 29 20 27 40 27 20 24 73 70 6c 69 74 20 32 2 ) '@' $split 2
9000: 6e 69 70 20 3b 0a 0a 3a 20 40 6e 69 63 6b 3e 63 nip ;..: @nick>c
9010: 68 61 74 20 28 20 61 64 64 72 20 75 20 2d 2d 20 hat ( addr u --
9020: 29 0a 20 20 20 20 68 6f 73 74 2e 6e 69 63 6b 3e ). host.nick>
9030: 70 6b 20 64 75 70 20 30 3d 20 21 21 6e 6f 2d 6e pk dup 0= !!no-n
9040: 69 63 6b 21 21 20 63 68 61 74 2d 6b 65 79 73 20 ick!! chat-keys
9050: 24 2b 5b 5d 21 20 3b 0a 0a 3a 20 40 6e 69 63 6b $+[]! ;..: @nick
9060: 73 3e 63 68 61 74 20 28 20 2d 2d 20 29 0a 20 20 s>chat ( -- ).
9070: 20 20 5b 27 5d 20 40 6e 69 63 6b 3e 63 68 61 74 ['] @nick>chat
9080: 20 40 61 72 67 2d 6c 6f 6f 70 20 3b 0a 0a 3a 20 @arg-loop ;..:
9090: 6e 69 63 6b 3e 63 68 61 74 20 28 20 61 64 64 72 nick>chat ( addr
90a0: 20 75 20 2d 2d 20 29 0a 20 20 20 20 40 2f 20 64 u -- ). @/ d
90b0: 75 70 20 49 46 0a 09 68 6f 73 74 2e 6e 69 63 6b up IF..host.nick
90c0: 3e 70 6b 20 64 75 70 20 30 3d 20 21 21 6e 6f 2d >pk dup 0= !!no-
90d0: 6e 69 63 6b 21 21 0a 09 5b 3a 20 32 73 77 61 70 nick!!..[: 2swap
90e0: 20 74 79 70 65 20 2e 22 20 40 22 20 74 79 70 65 type ." @" type
90f0: 20 3b 5d 20 24 74 6d 70 0a 20 20 20 20 45 4c 53 ;] $tmp. ELS
9100: 45 20 20 32 64 72 6f 70 20 20 54 48 45 4e 0a 20 E 2drop THEN.
9110: 20 20 20 63 68 61 74 2d 6b 65 79 73 20 24 2b 5b chat-keys $+[
9120: 5d 21 20 3b 0a 0a 3a 20 6e 69 63 6b 73 3e 63 68 ]! ;..: nicks>ch
9130: 61 74 20 28 20 2d 2d 20 29 0a 20 20 20 20 5b 27 at ( -- ). ['
9140: 5d 20 6e 69 63 6b 3e 63 68 61 74 20 61 72 67 2d ] nick>chat arg-
9150: 6c 6f 6f 70 20 3b 0a 0a 5c 20 64 6f 20 6f 74 72 loop ;..\ do otr
9160: 69 66 79 0a 0a 61 6c 73 6f 20 6e 65 74 32 6f 2d ify..also net2o-
9170: 62 61 73 65 0a 0a 3a 20 64 6f 2d 6f 74 72 69 66 base..: do-otrif
9180: 79 20 28 20 6e 20 2d 2d 20 29 20 3e 72 0a 20 20 y ( n -- ) >r.
9190: 20 20 6d 73 67 2d 67 72 6f 75 70 24 20 24 40 20 msg-group$ $@
91a0: 3e 67 72 6f 75 70 20 6d 73 67 2d 67 72 6f 75 70 >group msg-group
91b0: 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d 20 24 40 -o .msg:log[] $@
91c0: 0a 20 20 20 20 72 3e 20 63 65 6c 6c 73 20 64 75 . r> cells du
91d0: 70 20 30 3c 20 49 46 20 20 6f 76 65 72 20 2b 20 p 0< IF over +
91e0: 30 20 6d 61 78 20 20 54 48 45 4e 20 73 61 66 65 0 max THEN safe
91f0: 2f 73 74 72 69 6e 67 0a 20 20 20 20 49 46 20 20 /string. IF
9200: 24 40 0a 09 32 64 75 70 20 2b 20 32 20 2d 20 63 $@..2dup + 2 - c
9210: 40 20 24 38 30 20 61 6e 64 20 64 75 70 20 3e 72 @ $80 and dup >r
9220: 0a 09 49 46 20 20 6d 73 67 2d 64 65 63 2d 73 69 ..IF msg-dec-si
9230: 67 3f 20 20 45 4c 53 45 20 20 70 6b 2d 73 69 67 g? ELSE pk-sig
9240: 3f 20 20 54 48 45 4e 20 20 21 21 73 69 67 21 21 ? THEN !!sig!!
9250: 0a 09 32 64 75 70 20 2b 20 73 69 67 70 6b 73 69 ..2dup + sigpksi
9260: 7a 65 23 20 2d 20 73 69 67 70 6b 73 69 7a 65 23 ze# - sigpksize#
9270: 0a 09 6f 76 65 72 20 6b 65 79 73 69 7a 65 20 70 ..over keysize p
9280: 6b 40 20 6b 65 79 7c 20 73 74 72 3d 20 49 46 0a k@ key| str= IF.
9290: 09 20 20 20 20 6b 65 79 73 69 7a 65 20 2f 73 74 . keysize /st
92a0: 72 69 6e 67 20 24 2c 0a 09 20 20 20 20 72 3e 20 ring $,.. r>
92b0: 6e 65 77 2d 6f 74 72 73 69 67 20 24 2c 0a 09 20 new-otrsig $,..
92c0: 20 20 20 6d 73 67 2d 6f 74 72 69 66 79 0a 09 45 msg-otrify..E
92d0: 4c 53 45 0a 09 20 20 20 20 72 64 72 6f 70 20 32 LSE.. rdrop 2
92e0: 64 72 6f 70 20 32 64 72 6f 70 20 2e 22 20 6e 6f drop 2drop ." no
92f0: 74 20 79 6f 75 72 20 6d 65 73 73 61 67 65 21 22 t your message!"
9300: 20 66 6f 72 74 68 3a 63 72 0a 09 54 48 45 4e 0a forth:cr..THEN.
9310: 20 20 20 20 45 4c 53 45 20 20 64 72 6f 70 20 20 ELSE drop
9320: 54 48 45 4e 20 3b 0a 0a 70 72 65 76 69 6f 75 73 THEN ;..previous
9330: 0a 0a 5c 20 64 65 62 75 67 67 69 6e 67 20 61 69 ..\ debugging ai
9340: 64 73 20 66 6f 72 20 63 6c 61 73 73 65 73 0a 0a ds for classes..
9350: 3a 20 2e 61 63 6b 20 28 20 6f 3a 61 63 6b 20 2d : .ack ( o:ack -
9360: 2d 20 6f 3a 61 63 6b 20 29 0a 20 20 20 20 2e 22 - o:ack ). ."
9370: 20 61 63 6b 20 63 6f 6e 74 65 78 74 3a 22 20 63 ack context:" c
9380: 72 0a 20 20 20 20 2e 22 20 72 74 64 65 6c 61 79 r. ." rtdelay
9390: 3a 20 22 20 72 74 64 65 6c 61 79 20 36 34 40 20 : " rtdelay 64@
93a0: 73 36 34 2e 20 63 72 20 3b 0a 0a 3a 20 2e 63 6f s64. cr ;..: .co
93b0: 6e 74 65 78 74 20 28 20 6f 3a 63 6f 6e 74 65 78 ntext ( o:contex
93c0: 74 20 2d 2d 20 6f 3a 63 6f 6e 74 65 78 74 20 29 t -- o:context )
93d0: 0a 20 20 20 20 2e 22 20 43 6f 6e 6e 65 63 74 65 . ." Connecte
93e0: 64 20 77 69 74 68 3a 20 22 20 2e 63 6f 6e 2d 69 d with: " .con-i
93f0: 64 20 63 72 0a 20 20 20 20 61 63 6b 2d 63 6f 6e d cr. ack-con
9400: 74 65 78 74 20 40 20 3f 64 75 70 2d 49 46 20 20 text @ ?dup-IF
9410: 2e 2e 61 63 6b 20 20 54 48 45 4e 20 3b 0a 0a 3a ..ack THEN ;..:
9420: 20 2e 6e 6f 74 69 66 79 20 28 20 2d 2d 20 29 0a .notify ( -- ).
9430: 20 20 20 20 2e 22 20 6e 6f 74 69 66 79 20 22 20 ." notify "
9440: 63 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 3f 23 20 config:notify?#
9450: 3f 0a 20 20 20 20 2e 22 20 6c 65 64 20 22 20 63 ?. ." led " c
9460: 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 2d 72 67 62 onfig:notify-rgb
9470: 23 20 40 20 68 65 78 2e 20 63 6f 6e 66 69 67 3a # @ hex. config:
9480: 6e 6f 74 69 66 79 2d 6f 6e 23 20 3f 20 63 6f 6e notify-on# ? con
9490: 66 69 67 3a 6e 6f 74 69 66 79 2d 6f 66 66 23 20 fig:notify-off#
94a0: 3f 0a 20 20 20 20 2e 22 20 69 6e 74 65 72 76 61 ?. ." interva
94b0: 6c 20 22 20 63 6f 6e 66 69 67 3a 64 65 6c 74 61 l " config:delta
94c0: 2d 6e 6f 74 69 66 79 26 20 32 40 20 31 30 30 30 -notify& 2@ 1000
94d0: 30 30 30 20 75 6d 2f 6d 6f 64 20 2e 20 64 72 6f 000 um/mod . dro
94e0: 70 0a 20 20 20 20 2e 22 20 6d 6f 64 65 20 22 20 p. ." mode "
94f0: 63 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 2d 6d 6f config:notify-mo
9500: 64 65 23 20 40 20 2e 0a 20 20 20 20 63 6f 6e 66 de# @ .. conf
9510: 69 67 3a 6e 6f 74 69 66 79 2d 74 65 78 74 23 20 ig:notify-text#
9520: 40 0a 20 20 20 20 63 61 73 65 0a 09 2d 31 20 6f @. case..-1 o
9530: 66 20 20 2e 22 20 76 69 73 69 62 6c 65 22 20 20 f ." visible"
9540: 65 6e 64 6f 66 0a 09 30 20 6f 66 20 20 2e 22 20 endof..0 of ."
9550: 68 69 64 64 65 6e 22 20 20 65 6e 64 6f 66 0a 09 hidden" endof..
9560: 31 20 6f 66 20 20 2e 22 20 68 69 64 65 2d 6f 74 1 of ." hide-ot
9570: 72 22 20 20 65 6e 64 6f 66 0a 20 20 20 20 65 6e r" endof. en
9580: 64 63 61 73 65 0a 20 20 20 20 66 6f 72 74 68 3a dcase. forth:
9590: 63 72 20 3b 0a 0a 3a 20 67 65 74 2d 68 65 78 20 cr ;..: get-hex
95a0: 28 20 2d 2d 20 6e 20 29 0a 20 20 20 20 70 61 72 ( -- n ). par
95b0: 73 65 2d 6e 61 6d 65 20 27 24 27 20 73 6b 69 70 se-name '$' skip
95c0: 20 23 30 2e 20 32 73 77 61 70 20 5b 27 5d 20 3e #0. 2swap ['] >
95d0: 6e 75 6d 62 65 72 20 24 31 30 20 62 61 73 65 2d number $10 base-
95e0: 65 78 65 63 75 74 65 20 32 73 77 61 70 20 64 72 execute 2swap dr
95f0: 6f 70 20 3b 0a 3a 20 67 65 74 2d 64 65 63 20 28 op ;.: get-dec (
9600: 20 2d 2d 20 6e 20 29 0a 20 20 20 20 70 61 72 73 -- n ). pars
9610: 65 2d 6e 61 6d 65 20 27 23 27 20 73 6b 69 70 20 e-name '#' skip
9620: 23 30 2e 20 32 73 77 61 70 20 5b 27 5d 20 3e 6e #0. 2swap ['] >n
9630: 75 6d 62 65 72 20 23 31 30 20 62 61 73 65 2d 65 umber #10 base-e
9640: 78 65 63 75 74 65 20 32 73 77 61 70 20 64 72 6f xecute 2swap dro
9650: 70 20 3b 0a 0a 73 63 6f 70 65 3a 20 6e 6f 74 69 p ;..scope: noti
9660: 66 79 2d 63 6d 64 73 0a 0a 3a 20 6f 6e 20 28 20 fy-cmds..: on (
9670: 2d 2d 20 29 20 2d 32 20 63 6f 6e 66 69 67 3a 6e -- ) -2 config:n
9680: 6f 74 69 66 79 3f 23 20 21 20 3b 0a 3a 20 61 6c otify?# ! ;.: al
9690: 77 61 79 73 20 28 20 2d 2d 20 29 20 2d 33 20 63 ways ( -- ) -3 c
96a0: 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 3f 23 20 21 onfig:notify?# !
96b0: 20 3b 0a 3a 20 6f 66 66 20 28 20 2d 2d 20 29 20 ;.: off ( -- )
96c0: 30 20 63 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 3f 0 config:notify?
96d0: 23 20 21 20 3b 0a 3a 20 6c 65 64 20 28 20 2d 2d # ! ;.: led ( --
96e0: 20 29 20 5c 20 22 3c 72 72 67 67 62 62 3e 20 3c ) \ "<rrggbb> <
96f0: 6f 6e 2d 6d 73 3e 20 3c 6f 66 66 2d 6d 73 3e 22 on-ms> <off-ms>"
9700: 0a 20 20 20 20 67 65 74 2d 68 65 78 20 63 6f 6e . get-hex con
9710: 66 69 67 3a 6e 6f 74 69 66 79 2d 72 67 62 23 20 fig:notify-rgb#
9720: 21 0a 20 20 20 20 67 65 74 2d 64 65 63 20 23 35 !. get-dec #5
9730: 30 30 20 6d 61 78 20 63 6f 6e 66 69 67 3a 6e 6f 00 max config:no
9740: 74 69 66 79 2d 6f 6e 23 20 21 0a 20 20 20 20 67 tify-on# !. g
9750: 65 74 2d 64 65 63 20 23 35 30 30 20 6d 61 78 20 et-dec #500 max
9760: 63 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 2d 6f 66 config:notify-of
9770: 66 23 20 21 0a 20 20 20 20 6d 73 67 2d 62 75 69 f# !. msg-bui
9780: 6c 64 65 72 20 3b 0a 3a 20 69 6e 74 65 72 76 61 lder ;.: interva
9790: 6c 20 28 20 2d 2d 20 29 20 70 61 72 73 65 2d 6e l ( -- ) parse-n
97a0: 61 6d 65 0a 20 20 20 20 23 30 2e 20 32 73 77 61 ame. #0. 2swa
97b0: 70 20 5b 27 5d 20 3e 6e 75 6d 62 65 72 20 23 31 p ['] >number #1
97c0: 30 20 62 61 73 65 2d 65 78 65 63 75 74 65 20 31 0 base-execute 1
97d0: 20 3d 20 49 46 20 20 6e 69 70 20 63 40 20 63 61 = IF nip c@ ca
97e0: 73 65 0a 09 20 20 20 20 27 73 27 20 6f 66 20 20 se.. 's' of
97f0: 20 20 20 23 31 30 30 30 20 2a 20 65 6e 64 6f 66 #1000 * endof
9800: 0a 09 20 20 20 20 27 6d 27 20 6f 66 20 20 20 20 .. 'm' of
9810: 23 36 30 30 30 30 20 2a 20 65 6e 64 6f 66 0a 09 #60000 * endof..
9820: 20 20 20 20 27 68 27 20 6f 66 20 23 33 36 30 30 'h' of #3600
9830: 30 30 30 30 20 2a 20 65 6e 64 6f 66 0a 09 65 6e 0000 * endof..en
9840: 64 63 61 73 65 0a 20 20 20 20 45 4c 53 45 20 20 dcase. ELSE
9850: 32 64 72 6f 70 20 20 54 48 45 4e 20 20 23 31 30 2drop THEN #10
9860: 30 30 30 30 30 20 75 6d 2a 20 63 6f 6e 66 69 67 00000 um* config
9870: 3a 64 65 6c 74 61 2d 6e 6f 74 69 66 79 26 20 32 :delta-notify& 2
9880: 21 20 3b 0a 3a 20 6d 6f 64 65 20 28 20 2d 2d 20 ! ;.: mode ( --
9890: 29 0a 20 20 20 20 67 65 74 2d 64 65 63 20 33 20 ). get-dec 3
98a0: 61 6e 64 20 63 6f 6e 66 69 67 3a 6e 6f 74 69 66 and config:notif
98b0: 79 2d 6d 6f 64 65 23 20 21 20 6d 73 67 2d 62 75 y-mode# ! msg-bu
98c0: 69 6c 64 65 72 20 3b 0a 3a 20 76 69 73 69 62 6c ilder ;.: visibl
98d0: 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 63 6f 6e e ( -- ). con
98e0: 66 69 67 3a 6e 6f 74 69 66 79 2d 74 65 78 74 23 fig:notify-text#
98f0: 20 66 6f 72 74 68 3a 6f 6e 20 3b 0a 3a 20 68 69 forth:on ;.: hi
9900: 64 64 65 6e 20 28 20 2d 2d 20 29 0a 20 20 20 20 dden ( -- ).
9910: 63 6f 6e 66 69 67 3a 6e 6f 74 69 66 79 2d 74 65 config:notify-te
9920: 78 74 23 20 66 6f 72 74 68 3a 6f 66 66 20 3b 0a xt# forth:off ;.
9930: 3a 20 68 69 64 65 2d 6f 74 72 20 28 20 2d 2d 20 : hide-otr ( --
9940: 29 0a 20 20 20 20 31 20 63 6f 6e 66 69 67 3a 6e ). 1 config:n
9950: 6f 74 69 66 79 2d 74 65 78 74 23 20 21 20 3b 0a otify-text# ! ;.
9960: 0a 7d 73 63 6f 70 65 0a 0a 3a 20 2e 63 68 61 74 .}scope..: .chat
9970: 68 65 6c 70 20 28 20 61 64 64 72 20 75 20 2d 2d help ( addr u --
9980: 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 2e 22 addr u ). ."
9990: 20 2f 22 20 73 6f 75 72 63 65 20 37 20 2f 73 74 /" source 7 /st
99a0: 72 69 6e 67 20 74 79 70 65 20 63 72 20 3b 0a 0a ring type cr ;..
99b0: 3a 20 2e 6e 32 6f 2d 76 65 72 73 69 6f 6e 20 28 : .n2o-version (
99c0: 20 2d 2d 20 29 0a 20 20 20 20 2e 22 20 6e 32 6f -- ). ." n2o
99d0: 2d 22 20 6e 65 74 32 6f 2d 76 65 72 73 69 6f 6e -" net2o-version
99e0: 20 66 6f 72 74 68 3a 74 79 70 65 20 3b 0a 3a 20 forth:type ;.:
99f0: 2e 67 66 6f 72 74 68 2d 76 65 72 73 69 6f 6e 20 .gforth-version
9a00: 28 20 2d 2d 20 29 0a 20 20 20 20 2e 22 20 67 66 ( -- ). ." gf
9a10: 6f 72 74 68 2d 22 0a 20 20 20 20 63 61 73 65 20 orth-". case
9a20: 74 68 72 65 61 64 69 6e 67 2d 6d 65 74 68 6f 64 threading-method
9a30: 0a 09 30 20 6f 66 20 64 65 62 75 67 67 69 6e 67 ..0 of debugging
9a40: 2d 6d 65 74 68 6f 64 20 30 3d 20 49 46 20 2e 22 -method 0= IF ."
9a50: 20 66 61 73 74 2d 22 20 20 54 48 45 4e 20 20 65 fast-" THEN e
9a60: 6e 64 6f 66 0a 09 31 20 6f 66 20 2e 22 20 69 74 ndof..1 of ." it
9a70: 63 2d 22 20 65 6e 64 6f 66 0a 09 32 20 6f 66 20 c-" endof..2 of
9a80: 2e 22 20 64 69 74 63 2d 22 20 65 6e 64 6f 66 0a ." ditc-" endof.
9a90: 20 20 20 20 65 6e 64 63 61 73 65 0a 20 20 20 20 endcase.
9aa0: 76 65 72 73 69 6f 6e 2d 73 74 72 69 6e 67 20 66 version-string f
9ab0: 6f 72 74 68 3a 74 79 70 65 20 27 2d 27 20 66 6f orth:type '-' fo
9ac0: 72 74 68 3a 65 6d 69 74 0a 20 20 20 20 6d 61 63 rth:emit. mac
9ad0: 68 69 6e 65 20 66 6f 72 74 68 3a 74 79 70 65 20 hine forth:type
9ae0: 3b 0a 0a 66 6f 72 77 61 72 64 20 61 76 61 6c 61 ;..forward avala
9af0: 6e 63 68 65 2d 74 65 78 74 0a 0a 66 61 6c 73 65 nche-text..false
9b00: 20 76 61 6c 75 65 20 61 77 61 79 3f 0a 0a 3a 20 value away?..:
9b10: 67 72 6f 75 70 23 6d 61 70 20 28 20 78 74 20 2d group#map ( xt -
9b20: 2d 20 29 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 - ). msg-grou
9b30: 70 23 20 73 77 61 70 20 5b 7b 3a 20 78 74 3a 20 p# swap [{: xt:
9b40: 78 74 20 3a 7d 6c 20 63 65 6c 6c 2b 20 24 40 20 xt :}l cell+ $@
9b50: 64 72 6f 70 20 63 65 6c 6c 2b 20 2e 78 74 20 3b drop cell+ .xt ;
9b60: 5d 20 23 6d 61 70 20 3b 0a 0a 75 76 61 6c 2d 6f ] #map ;..uval-o
9b70: 20 63 68 61 74 2d 63 6d 64 2d 6f 0a 0a 6f 62 6a chat-cmd-o..obj
9b80: 65 63 74 20 75 63 6c 61 73 73 20 63 68 61 74 2d ect uclass chat-
9b90: 63 6d 64 2d 6f 0a 61 6c 73 6f 20 6e 65 74 32 6f cmd-o.also net2o
9ba0: 2d 62 61 73 65 20 73 63 6f 70 65 3a 20 2f 63 68 -base scope: /ch
9bb0: 61 74 0a 75 6d 65 74 68 6f 64 20 2f 6d 65 20 28 at.umethod /me (
9bc0: 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 addr u -- ).
9bd0: 20 5c 55 20 6d 65 20 3c 61 63 74 69 6f 6e 3e 20 \U me <action>
9be0: 20 20 20 20 20 20 20 20 20 73 65 6e 64 20 73 74 send st
9bf0: 72 69 6e 67 20 61 73 20 61 63 74 69 6f 6e 0a 20 ring as action.
9c00: 20 20 20 5c 47 20 6d 65 3a 20 73 65 6e 64 20 72 \G me: send r
9c10: 65 6d 61 69 6e 69 6e 67 20 73 74 72 69 6e 67 20 emaining string
9c20: 61 73 20 61 63 74 69 6f 6e 0a 75 6d 65 74 68 6f as action.umetho
9c30: 64 20 2f 61 77 61 79 20 28 20 61 64 64 72 20 75 d /away ( addr u
9c40: 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 61 77 61 -- ). \U awa
9c50: 79 20 5b 3c 61 63 74 69 6f 6e 3e 5d 20 20 20 20 y [<action>]
9c60: 20 20 73 65 6e 64 20 73 74 72 69 6e 67 20 6f 72 send string or
9c70: 20 22 61 77 61 79 20 66 72 6f 6d 20 6b 65 79 62 "away from keyb
9c80: 6f 61 72 64 22 20 61 73 20 61 63 74 69 6f 6e 0a oard" as action.
9c90: 20 20 20 20 5c 47 20 61 77 61 79 3a 20 73 65 6e \G away: sen
9ca0: 64 20 73 74 72 69 6e 67 20 6f 72 20 22 61 77 61 d string or "awa
9cb0: 79 20 66 72 6f 6d 20 6b 65 79 62 6f 61 72 64 22 y from keyboard"
9cc0: 20 61 73 20 61 63 74 69 6f 6e 0a 73 79 6e 6f 6e as action.synon
9cd0: 79 6d 20 2f 62 61 63 6b 20 2f 61 77 61 79 0a 75 ym /back /away.u
9ce0: 6d 65 74 68 6f 64 20 2f 6f 74 72 20 28 20 61 64 method /otr ( ad
9cf0: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c 55 dr u -- ). \U
9d00: 20 6f 74 72 20 6f 6e 7c 6f 66 66 7c 6d 65 73 73 otr on|off|mess
9d10: 61 67 65 20 20 20 74 75 72 6e 20 6f 74 72 20 6d age turn otr m
9d20: 6f 64 65 20 6f 6e 2f 6f 66 66 20 28 6f 72 20 6f ode on/off (or o
9d30: 6e 65 2d 73 68 6f 74 29 0a 75 6d 65 74 68 6f 64 ne-shot).umethod
9d40: 20 2f 70 65 65 72 73 20 28 20 61 64 64 72 20 75 /peers ( addr u
9d50: 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 70 65 65 -- ). \U pee
9d60: 72 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 rs
9d70: 20 20 6c 69 73 74 20 70 65 65 72 73 0a 20 20 20 list peers.
9d80: 20 5c 47 20 70 65 65 72 73 3a 20 6c 69 73 74 20 \G peers: list
9d90: 70 65 65 72 73 20 69 6e 20 61 6c 6c 20 67 72 6f peers in all gro
9da0: 75 70 73 0a 75 6d 65 74 68 6f 64 20 2f 67 70 73 ups.umethod /gps
9db0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 ( addr u -- ).
9dc0: 20 20 20 5c 55 20 67 70 73 20 20 20 20 20 20 20 \U gps
9dd0: 20 20 20 20 20 20 20 20 20 20 20 73 65 6e 64 20 send
9de0: 63 6f 6f 72 64 69 6e 61 74 65 73 0a 20 20 20 20 coordinates.
9df0: 5c 47 20 67 70 73 3a 20 73 65 6e 64 20 79 6f 75 \G gps: send you
9e00: 72 20 63 6f 6f 72 64 69 6e 61 74 65 73 0a 73 79 r coordinates.sy
9e10: 6e 6f 6e 79 6d 20 2f 68 65 72 65 20 2f 67 70 73 nonym /here /gps
9e20: 0a 75 6d 65 74 68 6f 64 20 2f 63 68 61 74 73 20 .umethod /chats
9e30: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 ( addr u -- ).
9e40: 20 20 5c 55 20 63 68 61 74 73 20 20 20 20 20 20 \U chats
9e50: 20 20 20 20 20 20 20 20 20 20 6c 69 73 74 20 63 list c
9e60: 68 61 74 73 0a 20 20 20 20 5c 47 20 63 68 61 74 hats. \G chat
9e70: 73 3a 20 6c 69 73 74 20 61 6c 6c 20 63 68 61 74 s: list all chat
9e80: 73 0a 75 6d 65 74 68 6f 64 20 2f 6e 61 74 20 28 s.umethod /nat (
9e90: 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 addr u -- ).
9ea0: 20 5c 55 20 6e 61 74 20 20 20 20 20 20 20 20 20 \U nat
9eb0: 20 20 20 20 20 20 20 20 20 6c 69 73 74 20 4e 41 list NA
9ec0: 54 20 69 6e 66 6f 0a 20 20 20 20 5c 47 20 6e 61 T info. \G na
9ed0: 74 3a 20 6c 69 73 74 20 6e 61 74 20 74 72 61 76 t: list nat trav
9ee0: 65 72 73 61 6c 20 69 6e 66 6f 72 6d 61 74 69 6f ersal informatio
9ef0: 6e 20 6f 66 20 61 6c 6c 20 70 65 65 72 73 20 69 n of all peers i
9f00: 6e 20 61 6c 6c 20 67 72 6f 75 70 73 0a 75 6d 65 n all groups.ume
9f10: 74 68 6f 64 20 2f 72 65 6e 61 74 20 28 20 61 64 thod /renat ( ad
9f20: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c 55 dr u -- ). \U
9f30: 20 72 65 6e 61 74 20 20 20 20 20 20 20 20 20 20 renat
9f40: 20 20 20 20 20 20 72 65 64 6f 20 4e 41 54 20 74 redo NAT t
9f50: 72 61 76 65 72 73 61 6c 0a 20 20 20 20 5c 47 20 raversal. \G
9f60: 72 65 6e 61 74 3a 20 72 65 64 6f 20 6e 61 74 20 renat: redo nat
9f70: 74 72 61 76 65 72 73 61 6c 0a 75 6d 65 74 68 6f traversal.umetho
9f80: 64 20 2f 68 65 6c 70 20 28 20 61 64 64 72 20 75 d /help ( addr u
9f90: 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 68 65 6c -- ). \U hel
9fa0: 70 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 p
9fb0: 20 20 73 68 6f 77 20 68 65 6c 70 0a 20 20 20 20 show help.
9fc0: 5c 47 20 68 65 6c 70 3a 20 6c 69 73 74 20 68 65 \G help: list he
9fd0: 6c 70 0a 75 6d 65 74 68 6f 64 20 2f 6d 79 61 64 lp.umethod /myad
9fe0: 64 72 73 20 28 20 61 64 64 72 20 75 20 2d 2d 20 drs ( addr u --
9ff0: 29 0a 20 20 20 20 5c 55 20 6d 79 61 64 64 72 73 ). \U myaddrs
a000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 69 li
a010: 73 74 20 6d 79 20 61 64 64 72 65 73 73 65 73 0a st my addresses.
a020: 20 20 20 20 5c 47 20 6d 79 61 64 64 72 73 3a 20 \G myaddrs:
a030: 6c 69 73 74 20 6d 79 20 6f 77 6e 20 6c 6f 63 61 list my own loca
a040: 6c 20 61 64 64 72 65 73 73 65 73 20 28 64 65 62 l addresses (deb
a050: 75 67 67 69 6e 67 29 0a 75 6d 65 74 68 6f 64 20 ugging).umethod
a060: 2f 21 6d 79 61 64 64 72 73 20 28 20 61 64 64 72 /!myaddrs ( addr
a070: 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 21 u -- ). \U !
a080: 6d 79 61 64 64 72 73 20 20 20 20 20 20 20 20 20 myaddrs
a090: 20 20 20 20 72 65 2d 6f 62 74 61 69 6e 20 6d 79 re-obtain my
a0a0: 20 61 64 64 72 65 73 73 65 73 0a 20 20 20 20 5c addresses. \
a0b0: 47 20 21 6d 79 61 64 64 72 73 3a 20 69 66 20 61 G !myaddrs: if a
a0c0: 75 74 6f 6d 61 74 69 63 20 64 65 74 65 63 74 69 utomatic detecti
a0d0: 6f 6e 20 6f 66 20 61 64 64 72 65 73 73 20 63 68 on of address ch
a0e0: 61 6e 67 65 73 20 66 61 69 6c 2c 0a 20 20 20 20 anges fail,.
a0f0: 5c 47 20 21 6d 79 61 64 64 72 73 3a 20 79 6f 75 \G !myaddrs: you
a100: 20 63 61 6e 20 75 73 65 20 74 68 69 73 20 63 6f can use this co
a110: 6d 6d 61 6e 64 20 74 6f 20 72 65 2d 6f 62 74 61 mmand to re-obta
a120: 69 6e 20 79 6f 75 72 20 6c 6f 63 61 6c 20 61 64 in your local ad
a130: 64 72 65 73 73 65 73 0a 75 6d 65 74 68 6f 64 20 dresses.umethod
a140: 2f 6e 6f 74 69 66 79 20 28 20 61 64 64 72 20 75 /notify ( addr u
a150: 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 6e 6f 74 -- ). \U not
a160: 69 66 79 20 61 6c 77 61 79 73 7c 6f 6e 7c 6f 66 ify always|on|of
a170: 66 7c 6c 65 64 20 3c 72 67 62 3e 20 3c 6f 6e 2d f|led <rgb> <on-
a180: 6d 73 3e 20 3c 6f 66 66 2d 6d 73 3e 7c 69 6e 74 ms> <off-ms>|int
a190: 65 72 76 61 6c 20 3c 74 69 6d 65 3e 5b 73 6d 68 erval <time>[smh
a1a0: 5d 7c 6d 6f 64 65 20 30 2d 33 0a 20 20 20 20 5c ]|mode 0-3. \
a1b0: 47 20 6e 6f 74 69 66 79 3a 20 43 68 61 6e 67 65 G notify: Change
a1c0: 20 6e 6f 74 69 66 69 63 61 74 6f 6e 20 73 65 74 notificaton set
a1d0: 74 69 6e 67 73 0a 75 6d 65 74 68 6f 64 20 2f 62 tings.umethod /b
a1e0: 65 61 63 6f 6e 73 20 28 20 61 64 64 72 20 75 20 eacons ( addr u
a1f0: 2d 2d 20 29 0a 20 20 20 20 5c 55 20 62 65 61 63 -- ). \U beac
a200: 6f 6e 73 20 20 20 20 20 20 20 20 20 20 20 20 20 ons
a210: 20 6c 69 73 74 20 62 65 61 63 6f 6e 73 0a 20 20 list beacons.
a220: 20 20 5c 47 20 62 65 61 63 6f 6e 73 3a 20 6c 69 \G beacons: li
a230: 73 74 20 61 6c 6c 20 62 65 61 63 6f 6e 73 0a 75 st all beacons.u
a240: 6d 65 74 68 6f 64 20 2f 6e 32 6f 20 28 20 61 64 method /n2o ( ad
a250: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c 55 dr u -- ). \U
a260: 20 6e 32 6f 20 3c 63 6d 64 3e 20 20 20 20 20 20 n2o <cmd>
a270: 20 20 20 20 20 20 65 78 65 63 75 74 65 20 6e 32 execute n2
a280: 6f 20 63 6f 6d 6d 61 6e 64 0a 20 20 20 20 5c 47 o command. \G
a290: 20 6e 32 6f 3a 20 45 78 65 63 75 74 65 20 6e 6f n2o: Execute no
a2a0: 72 6d 61 6c 20 6e 32 6f 20 63 6f 6d 6d 61 6e 64 rmal n2o command
a2b0: 0a 75 6d 65 74 68 6f 64 20 2f 69 6e 76 69 74 61 .umethod /invita
a2c0: 74 69 6f 6e 73 20 28 20 61 64 64 72 20 75 20 2d tions ( addr u -
a2d0: 2d 20 29 0a 20 20 20 20 5c 55 20 69 6e 76 69 74 - ). \U invit
a2e0: 61 74 69 6f 6e 73 20 20 20 20 20 20 20 20 20 20 ations
a2f0: 68 61 6e 64 6c 65 20 69 6e 76 69 74 61 74 69 6f handle invitatio
a300: 6e 73 0a 20 20 20 20 5c 47 20 69 6e 76 69 74 61 ns. \G invita
a310: 74 69 6f 6e 73 3a 20 68 61 6e 64 6c 65 20 69 6e tions: handle in
a320: 76 69 74 61 74 69 6f 6e 73 3a 20 61 63 63 65 70 vitations: accep
a330: 74 2c 20 69 67 6e 6f 72 65 20 6f 72 20 62 6c 6f t, ignore or blo
a340: 63 6b 20 69 6e 76 69 74 61 74 69 6f 6e 73 0a 75 ck invitations.u
a350: 6d 65 74 68 6f 64 20 2f 73 79 6e 63 20 28 20 61 method /sync ( a
a360: 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c ddr u -- ). \
a370: 55 20 73 79 6e 63 20 5b 2b 64 61 74 65 5d 20 5b U sync [+date] [
a380: 2d 64 61 74 65 5d 20 73 79 6e 63 68 72 6f 6e 69 -date] synchroni
a390: 7a 65 20 6c 6f 67 73 0a 20 20 20 20 5c 47 20 73 ze logs. \G s
a3a0: 79 6e 63 3a 20 73 79 6e 63 68 72 6f 6e 69 7a 65 ync: synchronize
a3b0: 20 63 68 61 74 20 6c 6f 67 73 2c 20 73 74 61 72 chat logs, star
a3c0: 74 69 6e 67 20 61 6e 64 2f 6f 72 20 65 6e 64 69 ting and/or endi
a3d0: 6e 67 20 61 74 20 73 70 65 63 69 66 69 63 0a 20 ng at specific.
a3e0: 20 20 20 5c 47 20 73 79 6e 63 3a 20 74 69 6d 65 \G sync: time
a3f0: 2f 64 61 74 65 0a 75 6d 65 74 68 6f 64 20 2f 76 /date.umethod /v
a400: 65 72 73 69 6f 6e 20 28 20 61 64 64 72 20 75 20 ersion ( addr u
a410: 2d 2d 20 29 0a 20 20 20 20 5c 55 20 76 65 72 73 -- ). \U vers
a420: 69 6f 6e 20 20 20 20 20 20 20 20 20 20 20 20 20 ion
a430: 20 76 65 72 73 69 6f 6e 20 73 74 72 69 6e 67 0a version string.
a440: 20 20 20 20 5c 47 20 76 65 72 73 69 6f 6e 3a 20 \G version:
a450: 70 72 69 6e 74 20 76 65 72 73 69 6f 6e 20 73 74 print version st
a460: 72 69 6e 67 0a 75 6d 65 74 68 6f 64 20 2f 6c 6f ring.umethod /lo
a470: 67 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a g ( addr u -- ).
a480: 20 20 20 20 5c 55 20 6c 6f 67 20 5b 23 6c 69 6e \U log [#lin
a490: 65 73 5d 20 20 20 20 20 20 20 20 20 73 68 6f 77 es] show
a4a0: 20 6c 6f 67 0a 20 20 20 20 5c 47 20 6c 6f 67 3a log. \G log:
a4b0: 20 73 68 6f 77 20 74 68 65 20 6c 6f 67 2c 20 64 show the log, d
a4c0: 65 66 61 75 6c 74 20 69 73 20 61 20 73 63 72 65 efault is a scre
a4d0: 65 6e 66 75 6c 0a 75 6d 65 74 68 6f 64 20 2f 6c enful.umethod /l
a4e0: 6f 67 73 74 79 6c 65 20 28 20 61 64 64 72 20 75 ogstyle ( addr u
a4f0: 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 6c 6f 67 -- ). \U log
a500: 73 74 79 6c 65 20 5b 2b 2d 73 74 79 6c 65 5d 20 style [+-style]
a510: 20 20 73 65 74 20 6c 6f 67 20 73 74 79 6c 65 0a set log style.
a520: 20 20 20 20 5c 47 20 6c 6f 67 73 74 79 6c 65 3a \G logstyle:
a530: 20 73 65 74 20 6c 6f 67 20 73 74 79 6c 65 73 2c set log styles,
a540: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 the following s
a550: 65 74 74 69 6e 67 73 20 65 78 69 73 74 3a 0a 20 ettings exist:.
a560: 20 20 20 5c 47 20 6c 6f 67 73 74 79 6c 65 3a 20 \G logstyle:
a570: 2b 64 61 74 65 20 20 20 20 20 20 61 20 64 61 74 +date a dat
a580: 65 20 70 65 72 20 6c 6f 67 20 6c 69 6e 65 0a 20 e per log line.
a590: 20 20 20 5c 47 20 6c 6f 67 73 74 79 6c 65 3a 20 \G logstyle:
a5a0: 2b 6e 75 6d 20 20 20 20 20 20 20 61 20 6d 65 73 +num a mes
a5b0: 73 61 67 65 20 6e 75 6d 62 65 72 20 70 65 72 20 sage number per
a5c0: 6c 6f 67 20 6c 69 6e 65 0a 75 6d 65 74 68 6f 64 log line.umethod
a5d0: 20 2f 6f 74 72 69 66 79 20 28 20 61 64 64 72 20 /otrify ( addr
a5e0: 75 20 2d 2d 20 29 0a 20 20 20 20 5c 55 20 6f 74 u -- ). \U ot
a5f0: 72 69 66 79 20 23 6c 69 6e 65 5b 73 5d 20 20 20 rify #line[s]
a600: 20 20 20 6f 74 72 69 66 79 20 6d 65 73 73 61 67 otrify messag
a610: 65 0a 20 20 20 20 5c 47 20 6f 74 72 69 66 79 3a e. \G otrify:
a620: 20 74 75 72 6e 20 61 6e 20 6f 6c 64 65 72 20 6d turn an older m
a630: 65 73 73 61 67 65 20 6f 66 20 79 6f 75 72 73 20 essage of yours
a640: 69 6e 74 6f 20 61 6e 20 4f 54 52 20 6d 65 73 73 into an OTR mess
a650: 61 67 65 0a 75 6d 65 74 68 6f 64 20 2f 6c 6f 63 age.umethod /loc
a660: 6b 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a k ( addr u -- ).
a670: 20 20 20 20 5c 55 20 6c 6f 63 6b 20 7b 40 6e 69 \U lock {@ni
a680: 63 6b 7d 20 20 20 20 20 20 20 20 20 6c 6f 63 6b ck} lock
a690: 20 64 6f 77 6e 0a 20 20 20 20 5c 47 20 6c 6f 63 down. \G loc
a6a0: 6b 3a 20 6c 6f 63 6b 20 64 6f 77 6e 20 63 6f 6d k: lock down com
a6b0: 6d 75 6e 69 63 61 74 69 6f 6e 20 74 6f 20 6c 69 munication to li
a6c0: 73 74 20 6f 66 20 6e 69 63 6b 73 0a 75 6d 65 74 st of nicks.umet
a6d0: 68 6f 64 20 2f 75 6e 6c 6f 63 6b 20 28 20 61 64 hod /unlock ( ad
a6e0: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c 55 dr u -- ). \U
a6f0: 20 75 6e 6c 6f 63 6b 20 20 20 20 20 20 20 20 20 unlock
a700: 20 20 20 20 20 20 73 74 6f 70 20 6c 6f 63 6b 20 stop lock
a710: 64 6f 77 6e 0a 20 20 20 20 5c 47 20 75 6e 6c 6f down. \G unlo
a720: 63 6b 3a 20 73 74 6f 70 20 6c 6f 63 6b 20 64 6f ck: stop lock do
a730: 77 6e 0a 75 6d 65 74 68 6f 64 20 2f 6c 6f 63 6b wn.umethod /lock
a740: 3f 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a ? ( addr u -- ).
a750: 20 20 20 20 5c 55 20 6c 6f 63 6b 3f 20 20 20 20 \U lock?
a760: 20 20 20 20 20 20 20 20 20 20 20 20 63 68 65 63 chec
a770: 6b 20 6c 6f 63 6b 20 73 74 61 74 75 73 0a 20 20 k lock status.
a780: 20 20 5c 47 20 6c 6f 63 6b 3f 3a 20 72 65 70 6f \G lock?: repo
a790: 72 74 20 6c 6f 63 6b 20 73 74 61 74 75 73 0a 75 rt lock status.u
a7a0: 6d 65 74 68 6f 64 20 2f 70 65 72 6d 73 20 28 20 method /perms (
a7b0: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
a7c0: 5c 55 20 70 65 72 6d 73 20 72 6f 6c 65 73 20 7b \U perms roles {
a7d0: 40 6b 65 79 73 7d 20 20 73 65 74 20 61 6e 64 20 @keys} set and
a7e0: 63 68 61 6e 67 65 20 70 65 72 6d 69 73 73 69 6f change permissio
a7f0: 6e 73 20 6f 66 20 75 73 65 72 73 0a 20 20 20 20 ns of users.
a800: 5c 47 20 70 65 72 6d 73 3a 20 73 65 74 20 70 65 \G perms: set pe
a810: 72 6d 69 73 73 69 6f 6e 73 0a 75 6d 65 74 68 6f rmissions.umetho
a820: 64 20 2f 62 79 65 20 28 20 61 64 64 72 20 75 20 d /bye ( addr u
a830: 2d 2d 20 29 0a 20 20 20 20 5c 55 20 62 79 65 0a -- ). \U bye.
a840: 20 20 20 20 5c 47 20 62 79 65 3a 20 6c 65 61 76 \G bye: leav
a850: 65 73 20 74 68 65 20 63 75 72 72 65 6e 74 20 63 es the current c
a860: 68 61 74 0a 75 6d 65 74 68 6f 64 20 2f 63 68 61 hat.umethod /cha
a870: 74 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a t ( addr u -- ).
a880: 20 20 20 20 5c 55 20 63 68 61 74 20 5b 67 72 6f \U chat [gro
a890: 75 70 5d 5b 40 75 73 65 72 5d 20 20 73 77 69 74 up][@user] swit
a8a0: 63 68 2f 63 6f 6e 6e 65 63 74 20 63 68 61 74 0a ch/connect chat.
a8b0: 20 20 20 20 5c 47 20 63 68 61 74 3a 20 73 77 69 \G chat: swi
a8c0: 74 63 68 20 74 6f 20 63 68 61 74 20 77 69 74 68 tch to chat with
a8d0: 20 75 73 65 72 20 6f 72 20 67 72 6f 75 70 0a 75 user or group.u
a8e0: 6d 65 74 68 6f 64 20 2f 73 70 6c 69 74 20 28 20 method /split (
a8f0: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
a900: 5c 55 20 73 70 6c 69 74 20 20 20 20 20 20 20 20 \U split
a910: 20 20 20 20 20 20 20 20 73 70 6c 69 74 20 6c 6f split lo
a920: 61 64 0a 20 20 20 20 5c 47 20 73 70 6c 69 74 3a ad. \G split:
a930: 20 72 65 64 75 63 65 20 64 69 73 74 72 69 62 75 reduce distribu
a940: 74 69 6f 6e 20 6c 6f 61 64 20 62 79 20 72 65 63 tion load by rec
a950: 6f 6e 6e 65 63 74 69 6e 67 0a 65 6e 64 2d 63 6c onnecting.end-cl
a960: 61 73 73 20 63 68 61 74 2d 63 6d 64 73 0a 0a 63 ass chat-cmds..c
a970: 68 61 74 2d 63 6d 64 73 20 6e 65 77 20 43 6f 6e hat-cmds new Con
a980: 73 74 61 6e 74 20 74 65 78 74 2d 63 68 61 74 2d stant text-chat-
a990: 63 6d 64 2d 6f 0a 0a 74 65 78 74 2d 63 68 61 74 cmd-o..text-chat
a9a0: 2d 63 6d 64 2d 6f 20 74 6f 20 63 68 61 74 2d 63 -cmd-o to chat-c
a9b0: 6d 64 2d 6f 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 md-o..:noname (
a9c0: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
a9d0: 5b 3a 20 24 2c 20 6d 73 67 2d 61 63 74 69 6f 6e [: $, msg-action
a9e0: 20 3b 5d 20 73 65 6e 64 2d 61 76 61 6c 61 6e 63 ;] send-avalanc
a9f0: 68 65 20 3b 20 69 73 20 2f 6d 65 0a 0a 3a 6e 6f he ; is /me..:no
aa00: 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d name ( addr u --
aa10: 20 29 0a 20 20 20 20 64 75 70 20 30 3d 20 49 46 ). dup 0= IF
aa20: 20 20 32 64 72 6f 70 0a 09 61 77 61 79 3f 20 49 2drop..away? I
aa30: 46 20 20 22 49 27 6d 20 62 61 63 6b 22 20 20 45 F "I'm back" E
aa40: 4c 53 45 20 20 22 41 77 61 79 20 66 72 6f 6d 20 LSE "Away from
aa50: 6b 65 79 62 6f 61 72 64 22 20 20 54 48 45 4e 0a keyboard" THEN.
aa60: 09 61 77 61 79 3f 20 30 3d 20 74 6f 20 61 77 61 .away? 0= to awa
aa70: 79 3f 0a 20 20 20 20 54 48 45 4e 0a 20 20 20 20 y?. THEN.
aa80: 5b 3a 20 24 2c 20 6d 73 67 2d 61 63 74 69 6f 6e [: $, msg-action
aa90: 20 3b 5d 20 73 65 6e 64 2d 61 76 61 6c 61 6e 63 ;] send-avalanc
aaa0: 68 65 20 3b 20 69 73 20 2f 61 77 61 79 0a 0a 3a he ; is /away..:
aab0: 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 noname ( addr u
aac0: 2d 2d 20 29 0a 20 20 20 20 32 64 75 70 20 73 22 -- ). 2dup s"
aad0: 20 6f 6e 22 20 73 74 72 3d 20 3e 72 0a 20 20 20 on" str= >r.
aae0: 20 32 64 75 70 20 73 22 20 6f 66 66 22 20 73 74 2dup s" off" st
aaf0: 72 3d 20 72 40 20 6f 72 20 49 46 20 20 20 32 64 r= r@ or IF 2d
ab00: 72 6f 70 0a 09 6d 73 67 2d 67 72 6f 75 70 2d 6f rop..msg-group-o
ab10: 20 72 40 20 49 46 20 20 2e 6d 73 67 3a 2b 6f 74 r@ IF .msg:+ot
ab20: 72 20 20 45 4c 53 45 20 20 2e 6d 73 67 3a 2d 6f r ELSE .msg:-o
ab30: 74 72 20 20 54 48 45 4e 0a 09 3c 69 6e 66 6f 3e tr THEN..<info>
ab40: 20 2e 22 20 3d 3d 3d 20 22 20 72 3e 20 49 46 20 ." === " r> IF
ab50: 20 2e 22 20 65 6e 74 65 72 22 20 20 45 4c 53 45 ." enter" ELSE
ab60: 20 20 2e 22 20 6c 65 61 76 65 22 20 20 54 48 45 ." leave" THE
ab70: 4e 0a 09 2e 22 20 20 6f 74 72 20 6d 6f 64 65 20 N..." otr mode
ab80: 3d 3d 3d 22 20 3c 64 65 66 61 75 6c 74 3e 20 66 ===" <default> f
ab90: 6f 72 74 68 3a 63 72 0a 20 20 20 20 45 4c 53 45 orth:cr. ELSE
aba0: 20 20 72 64 72 6f 70 0a 09 6d 73 67 2d 67 72 6f rdrop..msg-gro
abb0: 75 70 2d 6f 20 2e 6d 73 67 3a 6d 6f 64 65 20 40 up-o .msg:mode @
abc0: 20 3e 72 0a 09 6d 73 67 2d 67 72 6f 75 70 2d 6f >r..msg-group-o
abd0: 20 2e 6d 73 67 3a 2b 6f 74 72 20 61 76 61 6c 61 .msg:+otr avala
abe0: 6e 63 68 65 2d 74 65 78 74 0a 09 72 3e 20 6d 73 nche-text..r> ms
abf0: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6d g-group-o .msg:m
ac00: 6f 64 65 20 21 0a 20 20 20 20 54 48 45 4e 20 3b ode !. THEN ;
ac10: 20 69 73 20 2f 6f 74 72 0a 0a 3a 6e 6f 6e 61 6d is /otr..:nonam
ac20: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 e ( addr u -- )
ac30: 20 32 64 72 6f 70 0a 20 20 20 20 5b 3a 20 6d 73 2drop. [: ms
ac40: 67 3a 6e 61 6d 65 24 20 2e 67 72 6f 75 70 20 2e g:name$ .group .
ac50: 22 20 3a 20 22 0a 09 6d 73 67 3a 70 65 65 72 73 " : "..msg:peers
ac60: 5b 5d 20 24 40 20 62 6f 75 6e 64 73 20 3f 44 4f [] $@ bounds ?DO
ac70: 0a 09 20 20 20 20 73 70 61 63 65 20 49 20 40 20 .. space I @
ac80: 3e 6f 20 2e 63 6f 6e 2d 69 64 20 73 70 61 63 65 >o .con-id space
ac90: 0a 09 20 20 20 20 61 63 6b 40 20 2e 72 74 64 65 .. ack@ .rtde
aca0: 6c 61 79 20 36 34 40 20 36 34 3e 66 20 31 6e 20 lay 64@ 64>f 1n
acb0: 66 2a 20 28 2e 74 69 6d 65 29 20 6f 3e 0a 09 63 f* (.time) o>..c
acc0: 65 6c 6c 20 2b 4c 4f 4f 50 20 20 66 6f 72 74 68 ell +LOOP forth
acd0: 3a 63 72 20 3b 5d 20 67 72 6f 75 70 23 6d 61 70 :cr ;] group#map
ace0: 20 3b 20 69 73 20 2f 70 65 65 72 73 0a 0a 3a 6e ; is /peers..:n
acf0: 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d oname ( addr u -
ad00: 2d 20 29 20 20 32 64 72 6f 70 0a 20 20 20 20 63 - ) 2drop. c
ad10: 6f 6f 72 64 21 20 63 6f 6f 72 64 40 20 32 64 75 oord! coord@ 2du
ad20: 70 20 30 20 2d 73 6b 69 70 20 6e 69 70 20 30 3d p 0 -skip nip 0=
ad30: 20 49 46 20 20 32 64 72 6f 70 0a 20 20 20 20 45 IF 2drop. E
ad40: 4c 53 45 0a 09 5b 3a 20 24 2c 20 6d 73 67 2d 63 LSE..[: $, msg-c
ad50: 6f 6f 72 64 20 3b 5d 20 73 65 6e 64 2d 61 76 61 oord ;] send-ava
ad60: 6c 61 6e 63 68 65 0a 20 20 20 20 54 48 45 4e 20 lanche. THEN
ad70: 3b 20 69 73 20 2f 67 70 73 0a 0a 3a 6e 6f 6e 61 ; is /gps..:nona
ad80: 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 me ( addr u -- )
ad90: 0a 20 20 20 20 62 6c 20 73 6b 69 70 20 27 2f 27 . bl skip '/'
ada0: 20 73 6b 69 70 0a 20 20 20 20 32 64 75 70 20 5b skip. 2dup [
adb0: 3a 20 2e 22 20 20 20 20 20 5c 55 20 22 20 66 6f : ." \U " fo
adc0: 72 74 68 3a 74 79 70 65 20 3b 5d 20 24 74 6d 70 rth:type ;] $tmp
add0: 20 5b 27 5d 20 2e 63 68 61 74 68 65 6c 70 20 73 ['] .chathelp s
ade0: 65 61 72 63 68 2d 68 65 6c 70 0a 20 20 20 20 5b earch-help. [
adf0: 3a 20 2e 22 20 20 20 20 20 5c 47 20 22 20 66 6f : ." \G " fo
ae00: 72 74 68 3a 74 79 70 65 20 27 3a 27 20 66 6f 72 rth:type ':' for
ae10: 74 68 3a 65 6d 69 74 20 3b 5d 20 24 74 6d 70 20 th:emit ;] $tmp
ae20: 5b 27 5d 20 2e 63 6d 64 20 73 65 61 72 63 68 2d ['] .cmd search-
ae30: 68 65 6c 70 20 3b 0a 69 73 20 2f 68 65 6c 70 0a help ;.is /help.
ae40: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 .:noname ( addr
ae50: 75 20 2d 2d 20 29 0a 20 20 20 20 32 64 72 6f 70 u -- ). 2drop
ae60: 20 2e 69 6e 76 69 74 61 74 69 6f 6e 73 20 3b 20 .invitations ;
ae70: 69 73 20 2f 69 6e 76 69 74 61 74 69 6f 6e 73 0a is /invitations.
ae80: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 .:noname ( addr
ae90: 75 20 2d 2d 20 29 0a 20 20 20 20 32 64 72 6f 70 u -- ). 2drop
aea0: 20 2e 22 20 3d 3d 3d 3d 3d 20 63 68 61 74 73 3a ." ===== chats:
aeb0: 20 22 0a 20 20 20 20 5b 3a 20 20 6d 73 67 3a 6e ". [: msg:n
aec0: 61 6d 65 24 20 6d 73 67 2d 67 72 6f 75 70 24 20 ame$ msg-group$
aed0: 24 40 20 73 74 72 3d 20 49 46 20 2e 22 20 2a 22 $@ str= IF ." *"
aee0: 20 54 48 45 4e 0a 09 6d 73 67 3a 6e 61 6d 65 24 THEN..msg:name$
aef0: 20 2e 67 72 6f 75 70 0a 09 2e 22 20 5b 22 20 6d .group..." [" m
af00: 73 67 3a 70 65 65 72 73 5b 5d 20 24 5b 5d 23 20 sg:peers[] $[]#
af10: 30 20 2e 72 20 2e 22 20 5d 23 22 0a 09 6d 73 67 0 .r ." ]#"..msg
af20: 3a 6c 6f 67 5b 5d 20 24 5b 5d 23 20 75 2e 20 3b :log[] $[]# u. ;
af30: 5d 20 67 72 6f 75 70 23 6d 61 70 0a 20 20 20 20 ] group#map.
af40: 2e 22 20 3d 3d 3d 3d 3d 22 20 66 6f 72 74 68 3a ." =====" forth:
af50: 63 72 20 3b 20 69 73 20 2f 63 68 61 74 73 0a 0a cr ; is /chats..
af60: 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 :noname ( addr u
af70: 20 2d 2d 20 29 20 20 32 64 72 6f 70 0a 20 20 20 -- ) 2drop.
af80: 20 5b 3a 20 20 2e 22 20 3d 3d 3d 3d 3d 20 47 72 [: ." ===== Gr
af90: 6f 75 70 3a 20 22 20 6d 73 67 3a 6e 61 6d 65 24 oup: " msg:name$
afa0: 20 2e 67 72 6f 75 70 20 2e 22 20 20 3d 3d 3d 3d .group ." ====
afb0: 3d 22 20 66 6f 72 74 68 3a 63 72 0a 09 6d 73 67 =" forth:cr..msg
afc0: 3a 70 65 65 72 73 5b 5d 20 24 40 20 62 6f 75 6e :peers[] $@ boun
afd0: 64 73 20 3f 44 4f 0a 09 20 20 20 20 2e 22 20 2d ds ?DO.. ." -
afe0: 2d 2d 20 22 20 49 20 40 20 3e 6f 20 2e 63 6f 6e -- " I @ >o .con
aff0: 2d 69 64 20 2e 22 20 3a 20 22 20 72 65 74 75 72 -id ." : " retur
b000: 6e 2d 61 64 64 72 65 73 73 20 2e 61 64 64 72 2d n-address .addr-
b010: 70 61 74 68 0a 09 20 20 20 20 2e 22 20 20 2d 2d path.. ." --
b020: 2d 22 20 66 6f 72 74 68 3a 63 72 20 2e 6e 61 74 -" forth:cr .nat
b030: 2d 61 64 64 72 73 20 6f 3e 0a 09 63 65 6c 6c 20 -addrs o>..cell
b040: 2b 4c 4f 4f 50 20 3b 5d 20 67 72 6f 75 70 23 6d +LOOP ;] group#m
b050: 61 70 20 3b 20 69 73 20 2f 6e 61 74 0a 0a 3a 6e ap ; is /nat..:n
b060: 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d oname ( addr u -
b070: 2d 20 29 0a 20 20 20 20 32 64 72 6f 70 0a 20 20 - ). 2drop.
b080: 20 20 2e 22 20 3d 3d 3d 3d 3d 20 61 6c 6c 20 3d ." ===== all =
b090: 3d 3d 3d 3d 22 20 66 6f 72 74 68 3a 63 72 20 20 ====" forth:cr
b0a0: 20 20 2e 6d 79 2d 61 64 64 72 24 73 0a 20 20 20 .my-addr$s.
b0b0: 20 2e 22 20 3d 3d 3d 3d 3d 20 70 75 62 6c 69 63 ." ===== public
b0c0: 20 3d 3d 3d 3d 3d 22 20 66 6f 72 74 68 3a 63 72 =====" forth:cr
b0d0: 20 2e 70 75 62 2d 61 64 64 72 24 73 0a 20 20 20 .pub-addr$s.
b0e0: 20 2e 22 20 3d 3d 3d 3d 3d 20 70 72 69 76 61 74 ." ===== privat
b0f0: 65 20 3d 3d 3d 3d 3d 22 20 66 6f 72 74 68 3a 63 e =====" forth:c
b100: 72 20 2e 70 72 69 76 2d 61 64 64 72 24 73 20 3b r .priv-addr$s ;
b110: 20 69 73 20 2f 6d 79 61 64 64 72 73 0a 3a 6e 6f is /myaddrs.:no
b120: 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d name ( addr u --
b130: 20 29 0a 20 20 20 20 32 64 72 6f 70 20 21 6d 79 ). 2drop !my
b140: 2d 61 64 64 72 20 3b 20 69 73 20 2f 21 6d 79 61 -addr ; is /!mya
b150: 64 64 72 73 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 ddrs..:noname (
b160: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
b170: 5b 27 5d 20 6e 6f 74 69 66 79 2d 63 6d 64 73 20 ['] notify-cmds
b180: 65 76 61 6c 75 61 74 65 2d 69 6e 20 2e 6e 6f 74 evaluate-in .not
b190: 69 66 79 20 3b 20 69 73 20 2f 6e 6f 74 69 66 79 ify ; is /notify
b1a0: 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 ..:noname ( addr
b1b0: 20 75 20 2d 2d 20 29 0a 20 20 20 20 32 64 72 6f u -- ). 2dro
b1c0: 70 20 2e 22 20 3d 3d 3d 20 62 65 61 63 6f 6e 73 p ." === beacons
b1d0: 20 3d 3d 3d 22 20 66 6f 72 74 68 3a 63 72 0a 20 ===" forth:cr.
b1e0: 20 20 20 62 65 61 63 6f 6e 73 23 20 5b 3a 20 64 beacons# [: d
b1f0: 75 70 20 24 40 20 2e 61 64 64 72 65 73 73 20 73 up $@ .address s
b200: 70 61 63 65 0a 20 20 20 20 20 20 63 65 6c 6c 2b pace. cell+
b210: 20 24 40 20 6f 76 65 72 20 36 34 40 20 2e 74 69 $@ over 64@ .ti
b220: 63 6b 73 20 73 70 61 63 65 0a 20 20 20 20 20 20 cks space.
b230: 31 20 36 34 73 20 73 61 66 65 2f 73 74 72 69 6e 1 64s safe/strin
b240: 67 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 20 20 g bounds ?DO..
b250: 49 20 32 40 20 3f 64 75 70 2d 49 46 20 2e 2e 63 I 2@ ?dup-IF ..c
b260: 6f 6e 2d 69 64 20 73 70 61 63 65 20 54 48 45 4e on-id space THEN
b270: 20 2e 6e 61 6d 65 0a 20 20 20 20 20 20 32 20 63 .name. 2 c
b280: 65 6c 6c 73 20 2b 4c 4f 4f 50 20 66 6f 72 74 68 ells +LOOP forth
b290: 3a 63 72 20 3b 5d 20 23 6d 61 70 20 3b 20 69 73 :cr ;] #map ; is
b2a0: 20 2f 62 65 61 63 6f 6e 73 0a 0a 3a 6e 6f 6e 61 /beacons..:nona
b2b0: 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 me ( addr u -- )
b2c0: 0a 20 20 20 20 73 3e 75 6e 75 6d 62 65 72 3f 20 . s>unumber?
b2d0: 49 46 20 20 64 72 6f 70 20 20 45 4c 53 45 20 20 IF drop ELSE
b2e0: 32 64 72 6f 70 20 30 20 20 54 48 45 4e 20 20 63 2drop 0 THEN c
b2f0: 65 6c 6c 73 20 3e 72 0a 20 20 20 20 6d 73 67 2d ells >r. msg-
b300: 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 70 65 65 group-o .msg:pee
b310: 72 73 5b 5d 20 24 40 20 72 40 20 75 3c 3d 20 49 rs[] $@ r@ u<= I
b320: 46 20 20 64 72 6f 70 20 72 64 72 6f 70 20 20 45 F drop rdrop E
b330: 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 72 3e XIT THEN. r>
b340: 20 2b 20 40 20 3e 6f 20 6f 20 74 6f 20 63 6f 6e + @ >o o to con
b350: 6e 65 63 74 69 6f 6e 0a 20 20 20 20 2e 22 20 3d nection. ." =
b360: 3d 3d 20 73 79 6e 63 20 3d 3d 3d 22 20 66 6f 72 == sync ===" for
b370: 74 68 3a 63 72 0a 20 20 20 20 6e 65 74 32 6f 2d th:cr. net2o-
b380: 63 6f 64 65 20 65 78 70 65 63 74 2d 6d 73 67 20 code expect-msg
b390: 5b 3a 20 6d 73 67 2d 67 72 6f 75 70 20 6c 61 73 [: msg-group las
b3a0: 74 3f 2c 20 3b 5d 20 5b 6d 73 67 2c 5d 20 65 6e t?, ;] [msg,] en
b3b0: 64 2d 63 6f 64 65 20 6f 3e 20 3b 20 69 73 20 2f d-code o> ; is /
b3c0: 73 79 6e 63 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 sync..:noname (
b3d0: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 addr u -- ).
b3e0: 32 64 72 6f 70 20 2e 6e 32 6f 2d 76 65 72 73 69 2drop .n2o-versi
b3f0: 6f 6e 20 73 70 61 63 65 20 2e 67 66 6f 72 74 68 on space .gforth
b400: 2d 76 65 72 73 69 6f 6e 20 66 6f 72 74 68 3a 63 -version forth:c
b410: 72 20 3b 20 69 73 20 2f 76 65 72 73 69 6f 6e 0a r ; is /version.
b420: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 .:noname ( addr
b430: 75 20 2d 2d 20 29 0a 20 20 20 20 73 3e 75 6e 75 u -- ). s>unu
b440: 6d 62 65 72 3f 20 49 46 20 20 64 72 6f 70 20 3e mber? IF drop >
b450: 72 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20 72 r ELSE 2drop r
b460: 6f 77 73 20 3e 72 20 20 54 48 45 4e 0a 20 20 20 ows >r THEN.
b470: 20 6d 73 67 2d 67 72 6f 75 70 24 20 24 40 20 3e msg-group$ $@ >
b480: 67 72 6f 75 70 20 70 75 72 67 65 2d 6c 6f 67 0a group purge-log.
b490: 20 20 20 20 72 3e 20 20 64 69 73 70 6c 61 79 2d r> display-
b4a0: 6c 61 73 74 6e 20 3b 20 69 73 20 2f 6c 6f 67 0a lastn ; is /log.
b4b0: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 .:noname ( addr
b4c0: 75 20 2d 2d 20 29 0a 20 20 20 20 5b 27 5d 20 6c u -- ). ['] l
b4d0: 6f 67 73 74 79 6c 65 73 20 65 76 61 6c 75 61 74 ogstyles evaluat
b4e0: 65 2d 69 6e 20 3b 20 69 73 20 2f 6c 6f 67 73 74 e-in ; is /logst
b4f0: 79 6c 65 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 yle..:noname ( a
b500: 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5b ddr u -- ). [
b510: 3a 20 42 45 47 49 4e 20 20 62 6c 20 24 73 70 6c : BEGIN bl $spl
b520: 69 74 20 32 3e 72 20 64 75 70 20 20 57 48 49 4c it 2>r dup WHIL
b530: 45 20 20 73 3e 6e 75 6d 62 65 72 3f 20 57 48 49 E s>number? WHI
b540: 4c 45 0a 09 09 20 20 20 20 64 72 6f 70 20 64 6f LE... drop do
b550: 2d 6f 74 72 69 66 79 20 20 32 72 3e 20 20 52 45 -otrify 2r> RE
b560: 50 45 41 54 20 54 48 45 4e 0a 09 32 64 72 6f 70 PEAT THEN..2drop
b570: 20 32 72 3e 20 32 64 72 6f 70 20 20 6e 6f 77 3e 2r> 2drop now>
b580: 6f 74 72 0a 20 20 20 20 3b 5d 20 28 73 65 6e 64 otr. ;] (send
b590: 2d 61 76 61 6c 61 6e 63 68 65 29 20 64 72 6f 70 -avalanche) drop
b5a0: 20 2e 63 68 61 74 20 73 61 76 65 2d 6d 73 67 73 .chat save-msgs
b5b0: 26 20 3b 20 69 73 20 2f 6f 74 72 69 66 79 0a 0a & ; is /otrify..
b5c0: 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 :noname ( addr u
b5d0: 20 2d 2d 20 29 0a 20 20 20 20 6d 73 67 2d 67 72 -- ). msg-gr
b5e0: 6f 75 70 2d 6f 20 2e 6d 73 67 3a 2d 6c 6f 63 6b oup-o .msg:-lock
b5f0: 0a 20 20 20 20 77 6f 72 64 2d 61 72 67 73 20 5b . word-args [
b600: 27 5d 20 61 72 67 73 3e 6b 65 79 6c 69 73 74 20 '] args>keylist
b610: 65 78 65 63 75 74 65 2d 70 61 72 73 69 6e 67 0a execute-parsing.
b620: 20 20 20 20 5b 3a 20 6b 65 79 2d 6c 69 73 74 20 [: key-list
b630: 76 2d 65 6e 63 24 20 24 2c 20 6e 65 74 32 6f 2d v-enc$ $, net2o-
b640: 62 61 73 65 3a 6d 73 67 2d 6c 6f 63 6b 20 3b 5d base:msg-lock ;]
b650: 20 73 65 6e 64 2d 61 76 61 6c 61 6e 63 68 65 0a send-avalanche.
b660: 20 20 20 20 76 6b 65 79 20 6b 65 79 73 69 7a 65 vkey keysize
b670: 20 24 6d 61 6b 65 20 6d 73 67 2d 67 72 6f 75 70 $make msg-group
b680: 2d 6f 20 2e 6d 73 67 3a 6b 65 79 73 5b 5d 20 3e -o .msg:keys[] >
b690: 62 61 63 6b 0a 20 20 20 20 6d 73 67 2d 67 72 6f back. msg-gro
b6a0: 75 70 2d 6f 20 2e 6d 73 67 3a 2b 6c 6f 63 6b 0a up-o .msg:+lock.
b6b0: 3b 20 69 73 20 2f 6c 6f 63 6b 0a 3a 6e 6f 6e 61 ; is /lock.:nona
b6c0: 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 me ( addr u -- )
b6d0: 0a 20 20 20 20 32 64 72 6f 70 20 6d 73 67 2d 67 . 2drop msg-g
b6e0: 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 2d 6c 6f 63 roup-o .msg:-loc
b6f0: 6b 0a 20 20 20 20 5b 3a 20 6e 65 74 32 6f 2d 62 k. [: net2o-b
b700: 61 73 65 3a 6d 73 67 2d 75 6e 6c 6f 63 6b 20 3b ase:msg-unlock ;
b710: 5d 20 73 65 6e 64 2d 61 76 61 6c 61 6e 63 68 65 ] send-avalanche
b720: 0a 3b 20 69 73 20 2f 75 6e 6c 6f 63 6b 0a 3a 6e .; is /unlock.:n
b730: 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d oname ( addr u -
b740: 2d 20 29 0a 20 20 20 20 32 64 72 6f 70 20 6d 73 - ). 2drop ms
b750: 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 3f g-group-o .msg:?
b760: 6c 6f 63 6b 20 30 3d 20 49 46 20 20 2e 22 20 75 lock 0= IF ." u
b770: 6e 22 20 20 54 48 45 4e 20 20 2e 22 20 6c 6f 63 n" THEN ." loc
b780: 6b 65 64 22 20 66 6f 72 74 68 3a 63 72 0a 3b 20 ked" forth:cr.;
b790: 69 73 20 2f 6c 6f 63 6b 3f 0a 0a 24 31 30 30 20 is /lock?..$100
b7a0: 62 75 66 66 65 72 3a 20 70 65 72 6d 63 68 61 72 buffer: permchar
b7b0: 3e 62 69 74 73 0a 6d 73 67 3a 72 6f 6c 65 2d 61 >bits.msg:role-a
b7c0: 64 6d 69 6e 23 20 6d 73 67 3a 6b 65 79 2d 61 64 dmin# msg:key-ad
b7d0: 6d 69 6e 23 20 6d 73 67 3a 6d 6f 64 65 72 61 74 min# msg:moderat
b7e0: 6f 72 23 20 6f 72 20 6f 72 20 27 61 27 20 70 65 or# or or 'a' pe
b7f0: 72 6d 63 68 61 72 3e 62 69 74 73 20 2b 20 63 21 rmchar>bits + c!
b800: 0a 6d 73 67 3a 72 6f 6c 65 2d 61 64 6d 69 6e 23 .msg:role-admin#
b810: 20 27 72 27 20 70 65 72 6d 63 68 61 72 3e 62 69 'r' permchar>bi
b820: 74 73 20 2b 20 63 21 0a 6d 73 67 3a 6b 65 79 2d ts + c!.msg:key-
b830: 61 64 6d 69 6e 23 20 20 27 6b 27 20 70 65 72 6d admin# 'k' perm
b840: 63 68 61 72 3e 62 69 74 73 20 2b 20 63 21 0a 6d char>bits + c!.m
b850: 73 67 3a 6d 6f 64 65 72 61 74 6f 72 23 20 20 27 sg:moderator# '
b860: 6d 27 20 70 65 72 6d 63 68 61 72 3e 62 69 74 73 m' permchar>bits
b870: 20 2b 20 63 21 0a 6d 73 67 3a 74 72 6f 6c 6c 23 + c!.msg:troll#
b880: 20 20 20 20 20 20 27 74 27 20 70 65 72 6d 63 68 't' permch
b890: 61 72 3e 62 69 74 73 20 2b 20 63 21 0a 3a 20 3e ar>bits + c!.: >
b8a0: 70 65 72 6d 73 20 28 20 61 64 64 72 20 75 20 2d perms ( addr u -
b8b0: 2d 20 70 65 72 6d 73 20 29 0a 20 20 20 20 30 20 - perms ). 0
b8c0: 2d 72 6f 74 20 62 6f 75 6e 64 73 20 3f 44 4f 20 -rot bounds ?DO
b8d0: 20 49 20 63 40 20 70 65 72 6d 63 68 61 72 3e 62 I c@ permchar>b
b8e0: 69 74 73 20 2b 20 63 40 0a 09 64 75 70 20 30 3d its + c@..dup 0=
b8f0: 20 21 21 69 6e 76 2d 70 65 72 6d 21 21 20 6f 72 !!inv-perm!! or
b900: 20 20 4c 4f 4f 50 20 3b 0a 0a 3a 6e 6f 6e 61 6d LOOP ;..:nonam
b910: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a e ( addr u -- ).
b920: 20 20 20 20 77 6f 72 64 2d 61 72 67 73 20 5b 3a word-args [:
b930: 20 70 61 72 73 65 2d 6e 61 6d 65 20 3e 70 65 72 parse-name >per
b940: 6d 73 20 61 72 67 73 3e 6b 65 79 6c 69 73 74 20 ms args>keylist
b950: 3b 5d 20 65 78 65 63 75 74 65 2d 70 61 72 73 69 ;] execute-parsi
b960: 6e 67 0a 20 20 20 20 5b 7b 3a 20 70 65 72 6d 20 ng. [{: perm
b970: 3a 7d 6c 0a 09 70 65 72 6d 20 6b 65 79 2d 6c 69 :}l..perm key-li
b980: 73 74 20 5b 3a 20 6b 65 79 7c 20 24 2c 20 64 75 st [: key| $, du
b990: 70 20 75 6c 69 74 2c 20 6e 65 74 32 6f 2d 62 61 p ulit, net2o-ba
b9a0: 73 65 3a 6d 73 67 2d 70 65 72 6d 73 20 3b 5d 20 se:msg-perms ;]
b9b0: 24 5b 5d 6d 61 70 20 64 72 6f 70 0a 20 20 20 20 $[]map drop.
b9c0: 3b 5d 20 73 65 6e 64 2d 61 76 61 6c 61 6e 63 68 ;] send-avalanch
b9d0: 65 0a 3b 20 69 73 20 2f 70 65 72 6d 73 0a 0a 3a e.; is /perms..:
b9e0: 6e 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 noname ( addr u
b9f0: 2d 2d 20 29 0a 20 20 20 20 32 64 72 6f 70 20 2d -- ). 2drop -
ba00: 31 20 5b 49 46 44 45 46 5d 20 61 6e 64 72 6f 69 1 [IFDEF] androi
ba10: 64 20 61 6e 64 72 6f 69 64 3a 6c 65 76 65 6c 23 d android:level#
ba20: 20 5b 45 4c 53 45 5d 20 6c 65 76 65 6c 23 20 5b [ELSE] level# [
ba30: 54 48 45 4e 5d 20 2b 21 20 3b 20 69 73 20 2f 62 THEN] +! ; is /b
ba40: 79 65 0a 7d 73 63 6f 70 65 0a 0a 3a 20 3f 73 6c ye.}scope..: ?sl
ba50: 61 73 68 20 28 20 61 64 64 72 20 75 20 2d 2d 20 ash ( addr u --
ba60: 61 64 64 72 20 75 20 66 6c 61 67 20 29 0a 20 20 addr u flag ).
ba70: 20 20 6f 76 65 72 20 63 40 20 64 75 70 20 27 2f over c@ dup '/
ba80: 27 20 3d 20 73 77 61 70 20 27 5c 27 20 3d 20 6f ' = swap '\' = o
ba90: 72 20 3b 0a 0a 3a 20 64 6f 2d 63 68 61 74 2d 63 r ;..: do-chat-c
baa0: 6d 64 3f 20 28 20 61 64 64 72 20 75 20 2d 2d 20 md? ( addr u --
bab0: 74 20 2f 20 61 64 64 72 20 75 20 66 20 29 0a 20 t / addr u f ).
bac0: 20 20 20 3f 73 6c 61 73 68 20 64 75 70 20 30 3d ?slash dup 0=
bad0: 20 3f 45 58 49 54 20 20 64 72 6f 70 0a 20 20 20 ?EXIT drop.
bae0: 20 6f 76 65 72 20 27 2f 27 20 73 77 61 70 20 63 over '/' swap c
baf0: 21 20 62 6c 20 24 73 70 6c 69 74 20 32 73 77 61 ! bl $split 2swa
bb00: 70 0a 20 20 20 20 32 64 75 70 20 5b 27 5d 20 2f p. 2dup ['] /
bb10: 63 68 61 74 20 3e 62 6f 64 79 20 66 69 6e 64 2d chat >body find-
bb20: 6e 61 6d 65 2d 69 6e 0a 20 20 20 20 3f 64 75 70 name-in. ?dup
bb30: 2d 49 46 20 20 6e 69 70 20 6e 69 70 20 6e 61 6d -IF nip nip nam
bb40: 65 3e 69 6e 74 20 65 78 65 63 75 74 65 20 74 72 e>int execute tr
bb50: 75 65 0a 20 20 20 20 45 4c 53 45 20 20 64 72 6f ue. ELSE dro
bb60: 70 20 31 2d 20 2d 72 6f 74 20 2b 20 6f 76 65 72 p 1- -rot + over
bb70: 20 2d 20 66 61 6c 73 65 0a 20 20 20 20 54 48 45 - false. THE
bb80: 4e 20 3b 0a 0a 30 20 56 61 6c 75 65 20 6c 61 73 N ;..0 Value las
bb90: 74 2d 3e 69 6e 0a 0a 3a 20 3f 66 6c 75 73 68 2d t->in..: ?flush-
bba0: 74 65 78 74 20 28 20 61 64 64 72 20 2d 2d 20 29 text ( addr -- )
bbb0: 0a 20 20 20 20 6c 61 73 74 2d 3e 69 6e 20 3f 64 . last->in ?d
bbc0: 75 70 2d 30 3d 2d 49 46 20 20 73 6f 75 72 63 65 up-0=-IF source
bbd0: 20 64 72 6f 70 20 20 54 48 45 4e 0a 20 20 20 20 drop THEN.
bbe0: 74 75 63 6b 20 2d 20 64 75 70 20 49 46 0a 09 5c tuck - dup IF..\
bbf0: 20 2e 22 20 74 65 78 74 3a 20 27 22 20 66 6f 72 ." text: '" for
bc00: 74 68 3a 74 79 70 65 20 27 27 27 20 66 6f 72 74 th:type ''' fort
bc10: 68 3a 65 6d 69 74 20 66 6f 72 74 68 3a 63 72 0a h:emit forth:cr.
bc20: 09 24 2c 20 6d 73 67 2d 74 65 78 74 0a 20 20 20 .$, msg-text.
bc30: 20 45 4c 53 45 20 20 32 64 72 6f 70 20 20 54 48 ELSE 2drop TH
bc40: 45 4e 20 3b 0a 0a 3a 20 74 65 78 74 2d 72 65 63 EN ;..: text-rec
bc50: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 ( addr u -- ).
bc60: 20 20 20 32 64 72 6f 70 20 5b 27 5d 20 6e 6f 6f 2drop ['] noo
bc70: 70 20 72 65 63 74 79 70 65 2d 6e 61 6d 65 20 3b p rectype-name ;
bc80: 0a 3a 20 74 61 67 2d 72 65 63 20 28 20 61 64 64 .: tag-rec ( add
bc90: 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6f 76 65 r u -- ). ove
bca0: 72 20 63 40 20 27 23 27 20 3d 20 49 46 0a 09 6f r c@ '#' = IF..o
bcb0: 76 65 72 20 3f 66 6c 75 73 68 2d 74 65 78 74 20 ver ?flush-text
bcc0: 32 64 75 70 20 2b 20 74 6f 20 6c 61 73 74 2d 3e 2dup + to last->
bcd0: 69 6e 0a 09 5b 3a 20 31 20 2f 73 74 72 69 6e 67 in..[: 1 /string
bce0: 0a 09 20 20 20 20 5c 20 2e 22 20 74 61 67 3a 20 .. \ ." tag:
bcf0: 27 22 20 66 6f 72 74 68 3a 74 79 70 65 20 27 27 '" forth:type ''
bd00: 27 20 66 6f 72 74 68 3a 65 6d 69 74 20 66 6f 72 ' forth:emit for
bd10: 74 68 3a 63 72 0a 09 20 20 20 20 24 2c 20 6d 73 th:cr.. $, ms
bd20: 67 2d 74 61 67 0a 09 3b 5d 20 72 65 63 74 79 70 g-tag..;] rectyp
bd30: 65 2d 6e 61 6d 65 0a 20 20 20 20 45 4c 53 45 20 e-name. ELSE
bd40: 20 32 64 72 6f 70 20 72 65 63 74 79 70 65 2d 6e 2drop rectype-n
bd50: 75 6c 6c 20 20 54 48 45 4e 20 3b 0a 3a 20 70 6b ull THEN ;.: pk
bd60: 2d 72 65 63 20 28 20 61 64 64 72 20 75 20 2d 2d -rec ( addr u --
bd70: 20 29 0a 20 20 20 20 6f 76 65 72 20 63 40 20 27 ). over c@ '
bd80: 40 27 20 3d 20 49 46 20 20 32 64 75 70 20 31 20 @' = IF 2dup 1
bd90: 2f 73 74 72 69 6e 67 20 27 3a 27 20 2d 73 6b 69 /string ':' -ski
bda0: 70 20 6e 69 63 6b 3e 70 6b 0a 09 32 64 75 70 20 p nick>pk..2dup
bdb0: 64 30 3d 20 49 46 20 20 32 64 72 6f 70 20 32 64 d0= IF 2drop 2d
bdc0: 72 6f 70 20 72 65 63 74 79 70 65 2d 6e 75 6c 6c rop rectype-null
bdd0: 0a 09 45 4c 53 45 0a 09 20 20 20 20 32 3e 72 20 ..ELSE.. 2>r
bde0: 6f 76 65 72 20 3f 66 6c 75 73 68 2d 74 65 78 74 over ?flush-text
bdf0: 20 2b 20 74 6f 20 6c 61 73 74 2d 3e 69 6e 20 20 + to last->in
be00: 32 72 3e 0a 09 20 20 20 20 5b 3a 0a 09 09 5c 20 2r>.. [:...\
be10: 2e 22 20 73 69 67 6e 61 6c 3a 20 27 22 20 38 35 ." signal: '" 85
be20: 74 79 70 65 20 27 27 27 20 66 6f 72 74 68 3a 65 type ''' forth:e
be30: 6d 69 74 20 66 6f 72 74 68 3a 63 72 0a 09 09 24 mit forth:cr...$
be40: 2c 20 6d 73 67 2d 73 69 67 6e 61 6c 0a 09 20 20 , msg-signal..
be50: 20 20 3b 5d 20 72 65 63 74 79 70 65 2d 6e 61 6d ;] rectype-nam
be60: 65 0a 09 54 48 45 4e 0a 20 20 20 20 45 4c 53 45 e..THEN. ELSE
be70: 20 20 32 64 72 6f 70 20 72 65 63 74 79 70 65 2d 2drop rectype-
be80: 6e 75 6c 6c 20 20 54 48 45 4e 20 3b 0a 3a 20 63 null THEN ;.: c
be90: 68 61 69 6e 2d 72 65 63 20 28 20 61 64 64 72 20 hain-rec ( addr
bea0: 75 20 2d 2d 20 29 0a 20 20 20 20 6f 76 65 72 20 u -- ). over
beb0: 63 40 20 27 21 27 20 3d 20 49 46 0a 09 32 64 75 c@ '!' = IF..2du
bec0: 70 20 31 20 2f 73 74 72 69 6e 67 20 64 75 70 20 p 1 /string dup
bed0: 30 3d 20 49 46 20 20 32 64 72 6f 70 20 32 64 72 0= IF 2drop 2dr
bee0: 6f 70 20 72 65 63 74 79 70 65 2d 6e 75 6c 6c 20 op rectype-null
bef0: 20 45 58 49 54 20 20 54 48 45 4e 0a 09 73 6e 75 EXIT THEN..snu
bf00: 6d 62 65 72 3f 0a 09 63 61 73 65 0a 09 20 20 20 mber?..case..
bf10: 20 30 20 6f 66 20 20 65 6e 64 6f 66 0a 09 20 20 0 of endof..
bf20: 20 20 2d 31 20 6f 66 0a 09 09 6d 73 67 2d 67 72 -1 of...msg-gr
bf30: 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6c 6f 67 5b 5d oup-o .msg:log[]
bf40: 20 24 5b 5d 23 0a 09 09 6f 76 65 72 20 61 62 73 $[]#...over abs
bf50: 20 6f 76 65 72 20 75 3c 20 49 46 20 20 6f 76 65 over u< IF ove
bf60: 72 20 30 3c 20 49 46 20 20 2b 20 20 45 4c 53 45 r 0< IF + ELSE
bf70: 20 20 64 72 6f 70 20 20 54 48 45 4e 0a 09 09 20 drop THEN...
bf80: 20 20 20 3e 72 20 6f 76 65 72 20 3f 66 6c 75 73 >r over ?flus
bf90: 68 2d 74 65 78 74 20 2b 20 74 6f 20 6c 61 73 74 h-text + to last
bfa0: 2d 3e 69 6e 20 20 72 3e 0a 09 09 20 20 20 20 5b ->in r>... [
bfb0: 3a 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d : msg-group-o .m
bfc0: 73 67 3a 6c 6f 67 5b 5d 20 24 5b 5d 40 20 63 68 sg:log[] $[]@ ch
bfd0: 61 69 6e 2c 20 3b 5d 0a 09 09 20 20 20 20 72 65 ain, ;]... re
bfe0: 63 74 79 70 65 2d 6e 61 6d 65 20 20 45 58 49 54 ctype-name EXIT
bff0: 20 20 54 48 45 4e 0a 09 20 20 20 20 65 6e 64 6f THEN.. endo
c000: 66 0a 09 20 20 20 20 32 64 72 6f 70 0a 09 65 6e f.. 2drop..en
c010: 64 63 61 73 65 0a 20 20 20 20 54 48 45 4e 20 20 dcase. THEN
c020: 32 64 72 6f 70 20 20 72 65 63 74 79 70 65 2d 6e 2drop rectype-n
c030: 75 6c 6c 20 20 3b 0a 3a 20 68 74 74 70 2d 72 65 ull ;.: http-re
c040: 63 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a c ( addr u -- ).
c050: 20 20 20 20 32 64 75 70 20 22 68 74 74 70 73 3a 2dup "https:
c060: 2f 2f 22 20 73 74 72 69 6e 67 2d 70 72 65 66 69 //" string-prefi
c070: 78 3f 20 3e 72 0a 20 20 20 20 32 64 75 70 20 22 x? >r. 2dup "
c080: 68 74 74 70 3a 2f 2f 22 20 73 74 72 69 6e 67 2d http://" string-
c090: 70 72 65 66 69 78 3f 20 72 3e 20 6f 72 20 49 46 prefix? r> or IF
c0a0: 0a 09 6f 76 65 72 20 3f 66 6c 75 73 68 2d 74 65 ..over ?flush-te
c0b0: 78 74 20 32 64 75 70 20 2b 20 74 6f 20 6c 61 73 xt 2dup + to las
c0c0: 74 2d 3e 69 6e 0a 09 5b 3a 20 24 2c 20 6d 73 67 t->in..[: $, msg
c0d0: 2d 75 72 6c 20 3b 5d 20 72 65 63 74 79 70 65 2d -url ;] rectype-
c0e0: 6e 61 6d 65 0a 20 20 20 20 45 4c 53 45 20 20 32 name. ELSE 2
c0f0: 64 72 6f 70 20 72 65 63 74 79 70 65 2d 6e 75 6c drop rectype-nul
c100: 6c 20 20 54 48 45 4e 20 3b 0a 0a 24 56 61 72 69 l THEN ;..$Vari
c110: 61 62 6c 65 20 6d 73 67 2d 72 65 63 6f 67 6e 69 able msg-recogni
c120: 7a 65 72 0a 27 20 74 65 78 74 2d 72 65 63 20 27 zer.' text-rec '
c130: 20 68 74 74 70 2d 72 65 63 20 27 20 63 68 61 69 http-rec ' chai
c140: 6e 2d 72 65 63 20 27 20 74 61 67 2d 72 65 63 20 n-rec ' tag-rec
c150: 27 20 70 6b 2d 72 65 63 20 35 20 6d 73 67 2d 72 ' pk-rec 5 msg-r
c160: 65 63 6f 67 6e 69 7a 65 72 20 73 65 74 2d 73 74 ecognizer set-st
c170: 61 63 6b 0a 0a 3a 20 70 61 72 73 65 2d 74 65 78 ack..: parse-tex
c180: 74 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 t ( addr u -- )
c190: 6c 61 73 74 23 20 3e 72 20 20 66 6f 72 74 68 2d last# >r forth-
c1a0: 72 65 63 6f 67 6e 69 7a 65 72 20 3e 72 0a 20 20 recognizer >r.
c1b0: 20 20 30 20 74 6f 20 6c 61 73 74 2d 3e 69 6e 0a 0 to last->in.
c1c0: 20 20 20 20 6d 73 67 2d 72 65 63 6f 67 6e 69 7a msg-recogniz
c1d0: 65 72 20 74 6f 20 66 6f 72 74 68 2d 72 65 63 6f er to forth-reco
c1e0: 67 6e 69 7a 65 72 20 32 64 75 70 20 65 76 61 6c gnizer 2dup eval
c1f0: 75 61 74 65 0a 20 20 20 20 6c 61 73 74 2d 3e 69 uate. last->i
c200: 6e 20 49 46 20 20 2b 20 6c 61 73 74 2d 3e 69 6e n IF + last->in
c210: 20 74 75 63 6b 20 2d 20 20 54 48 45 4e 20 20 64 tuck - THEN d
c220: 75 70 20 49 46 0a 09 5c 20 2e 22 20 74 65 78 74 up IF..\ ." text
c230: 3a 20 27 22 20 66 6f 72 74 68 3a 74 79 70 65 20 : '" forth:type
c240: 27 27 27 20 66 6f 72 74 68 3a 65 6d 69 74 20 66 ''' forth:emit f
c250: 6f 72 74 68 3a 63 72 0a 09 24 2c 20 6d 73 67 2d orth:cr..$, msg-
c260: 74 65 78 74 0a 20 20 20 20 45 4c 53 45 20 20 32 text. ELSE 2
c270: 64 72 6f 70 20 20 54 48 45 4e 0a 20 20 20 20 72 drop THEN. r
c280: 3e 20 74 6f 20 66 6f 72 74 68 2d 72 65 63 6f 67 > to forth-recog
c290: 6e 69 7a 65 72 20 20 72 3e 20 74 6f 20 6c 61 73 nizer r> to las
c2a0: 74 23 20 3b 0a 0a 3a 20 61 76 61 6c 61 6e 63 68 t# ;..: avalanch
c2b0: 65 2d 74 65 78 74 20 28 20 61 64 64 72 20 75 20 e-text ( addr u
c2c0: 2d 2d 20 29 0a 20 20 20 20 3e 75 74 66 38 24 20 -- ). >utf8$
c2d0: 5b 27 5d 20 70 61 72 73 65 2d 74 65 78 74 20 73 ['] parse-text s
c2e0: 65 6e 64 2d 61 76 61 6c 61 6e 63 68 65 20 3b 0a end-avalanche ;.
c2f0: 0a 70 72 65 76 69 6f 75 73 0a 0a 3a 20 6c 6f 61 .previous..: loa
c300: 64 2d 6d 73 67 6e 20 28 20 61 64 64 72 20 75 20 d-msgn ( addr u
c310: 6e 20 2d 2d 20 29 0a 20 20 20 20 3e 72 20 6c 6f n -- ). >r lo
c320: 61 64 2d 6d 73 67 20 72 3e 20 64 69 73 70 6c 61 ad-msg r> displa
c330: 79 2d 6c 61 73 74 6e 20 3b 0a 0a 3a 20 2b 67 72 y-lastn ;..: +gr
c340: 6f 75 70 20 28 20 2d 2d 20 29 20 6d 73 67 2d 67 oup ( -- ) msg-g
c350: 72 6f 75 70 24 20 24 40 20 3e 67 72 6f 75 70 20 roup$ $@ >group
c360: 2b 75 6e 69 71 75 65 2d 63 6f 6e 20 3b 0a 0a 3a +unique-con ;..:
c370: 20 6d 73 67 2d 74 69 6d 65 6f 75 74 20 28 20 2d msg-timeout ( -
c380: 2d 20 29 0a 20 20 20 20 70 61 63 6b 65 74 73 32 - ). packets2
c390: 20 40 20 20 63 6f 6e 6e 65 63 74 65 64 2d 74 69 @ connected-ti
c3a0: 6d 65 6f 75 74 20 20 70 61 63 6b 65 74 73 32 20 meout packets2
c3b0: 40 20 3c 3e 0a 20 20 20 20 49 46 20 20 72 65 70 @ <>. IF rep
c3c0: 6c 79 28 20 2e 22 20 52 65 73 65 6e 64 20 74 6f ly( ." Resend to
c3d0: 20 22 20 70 75 62 6b 65 79 20 24 40 20 6b 65 79 " pubkey $@ key
c3e0: 3e 6e 69 63 6b 20 74 79 70 65 20 63 72 20 29 0a >nick type cr ).
c3f0: 09 74 69 6d 65 6f 75 74 2d 65 78 70 69 72 65 64 .timeout-expired
c400: 3f 20 49 46 0a 09 20 20 20 20 74 69 6d 65 6f 75 ? IF.. timeou
c410: 74 28 20 3c 65 72 72 3e 20 2e 22 20 45 78 63 65 t( <err> ." Exce
c420: 73 73 69 76 65 20 74 69 6d 65 6f 75 74 73 20 66 ssive timeouts f
c430: 72 6f 6d 20 22 0a 09 20 20 20 20 70 75 62 6b 65 rom ".. pubke
c440: 79 20 24 40 20 6b 65 79 3e 6e 69 63 6b 20 74 79 y $@ key>nick ty
c450: 70 65 20 2e 22 20 3a 20 22 0a 09 20 20 20 20 61 pe ." : ".. a
c460: 63 6b 40 20 2e 74 69 6d 65 6f 75 74 73 20 40 20 ck@ .timeouts @
c470: 2e 20 3c 64 65 66 61 75 6c 74 3e 20 63 72 20 29 . <default> cr )
c480: 0a 09 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 24 .. msg-group$
c490: 20 24 40 6c 65 6e 20 49 46 0a 09 09 6d 73 67 2d $@len IF...msg-
c4a0: 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6d 6f 64 group-o .msg:mod
c4b0: 65 20 64 75 70 20 40 20 6d 73 67 3a 6f 74 72 23 e dup @ msg:otr#
c4c0: 20 6f 72 20 73 77 61 70 0a 09 09 5b 3a 20 70 75 or swap...[: pu
c4d0: 62 6b 65 79 20 24 40 20 5b 27 5d 20 6c 65 66 74 bkey $@ ['] left
c4e0: 2c 20 73 65 6e 64 2d 61 76 61 6c 61 6e 63 68 65 , send-avalanche
c4f0: 20 3b 5d 20 21 77 72 61 70 70 65 72 0a 09 20 20 ;] !wrapper..
c500: 20 20 54 48 45 4e 0a 09 20 20 20 20 6e 65 74 32 THEN.. net2
c510: 6f 3a 64 69 73 70 6f 73 65 2d 63 6f 6e 74 65 78 o:dispose-contex
c520: 74 0a 09 20 20 20 20 45 58 49 54 0a 09 54 48 45 t.. EXIT..THE
c530: 4e 0a 20 20 20 20 45 4c 53 45 20 20 65 78 70 65 N. ELSE expe
c540: 63 74 65 64 40 20 75 3c 3d 20 49 46 20 20 2d 74 cted@ u<= IF -t
c550: 69 6d 65 6f 75 74 20 20 54 48 45 4e 20 20 54 48 imeout THEN TH
c560: 45 4e 20 3b 0a 0a 3a 20 2b 72 65 73 65 6e 64 2d EN ;..: +resend-
c570: 6d 73 67 20 28 20 2d 2d 20 29 0a 20 20 20 20 5b msg ( -- ). [
c580: 27 5d 20 6d 73 67 2d 74 69 6d 65 6f 75 74 20 69 '] msg-timeout i
c590: 73 20 74 69 6d 65 6f 75 74 2d 78 74 20 20 6f 2b s timeout-xt o+
c5a0: 74 69 6d 65 6f 75 74 20 3b 0a 0a 24 42 20 24 45 timeout ;..$B $E
c5b0: 20 32 56 61 6c 75 65 20 63 68 61 74 2d 62 75 66 2Value chat-buf
c5c0: 73 23 0a 0a 3a 20 2b 63 68 61 74 2d 63 6f 6e 74 s#..: +chat-cont
c5d0: 72 6f 6c 20 28 20 2d 2d 20 29 0a 20 20 20 20 2b rol ( -- ). +
c5e0: 72 65 73 65 6e 64 2d 6d 73 67 20 2b 66 6c 6f 77 resend-msg +flow
c5f0: 2d 63 6f 6e 74 72 6f 6c 20 3b 0a 0a 3a 20 63 68 -control ;..: ch
c600: 61 74 23 2d 63 6f 6e 6e 65 63 74 3f 20 28 20 61 at#-connect? ( a
c610: 64 64 72 20 75 20 62 75 66 31 20 62 75 66 32 20 ddr u buf1 buf2
c620: 2d 2d 2d 20 66 6c 61 67 20 29 0a 20 20 20 20 70 --- flag ). p
c630: 6b 2d 63 6f 6e 6e 65 63 74 3f 20 64 75 70 20 49 k-connect? dup I
c640: 46 20 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 3e 6f F connection >o
c650: 20 72 64 72 6f 70 20 2b 63 68 61 74 2d 63 6f 6e rdrop +chat-con
c660: 74 72 6f 6c 20 20 2b 67 72 6f 75 70 20 20 54 48 trol +group TH
c670: 45 4e 20 3b 0a 0a 3a 20 63 68 61 74 2d 63 6f 6e EN ;..: chat-con
c680: 6e 65 63 74 20 28 20 61 64 64 72 20 75 20 2d 2d nect ( addr u --
c690: 20 29 0a 20 20 20 20 63 68 61 74 2d 62 75 66 73 ). chat-bufs
c6a0: 23 20 63 68 61 74 23 2d 63 6f 6e 6e 65 63 74 3f # chat#-connect?
c6b0: 20 49 46 20 20 67 72 65 65 74 20 20 54 48 45 4e IF greet THEN
c6c0: 20 3b 0a 0a 3a 20 6b 65 79 2d 63 74 72 6c 62 69 ;..: key-ctrlbi
c6d0: 74 20 28 20 2d 2d 20 6e 20 29 0a 20 20 20 20 5c t ( -- n ). \
c6e0: 47 20 72 65 74 75 72 6e 20 61 20 62 69 74 20 6d G return a bit m
c6f0: 61 73 6b 20 66 6f 72 20 74 68 65 20 63 6f 6e 74 ask for the cont
c700: 72 6f 6c 20 6b 65 79 20 70 72 65 73 73 65 64 0a rol key pressed.
c710: 20 20 20 20 31 20 6b 65 79 20 64 75 70 20 62 6c 1 key dup bl
c720: 20 3c 20 3e 72 20 6c 73 68 69 66 74 20 72 3e 20 < >r lshift r>
c730: 61 6e 64 20 3b 0a 0a 3a 20 77 61 69 74 2d 6b 65 and ;..: wait-ke
c740: 79 20 28 20 2d 2d 20 29 0a 20 20 20 20 42 45 47 y ( -- ). BEG
c750: 49 4e 20 20 6b 65 79 2d 63 74 72 6c 62 69 74 20 IN key-ctrlbit
c760: 5b 20 31 20 63 74 72 6c 20 4c 20 6c 73 68 69 66 [ 1 ctrl L lshif
c770: 74 20 31 20 63 74 72 6c 20 5a 20 6c 73 68 69 66 t 1 ctrl Z lshif
c780: 74 20 6f 72 20 5d 4c 0a 20 20 20 20 61 6e 64 20 t or ]L. and
c790: 30 3d 20 20 55 4e 54 49 4c 20 3b 0a 0a 3a 20 63 0= UNTIL ;..: c
c7a0: 68 61 74 73 23 20 28 20 2d 2d 20 6e 20 29 0a 20 hats# ( -- n ).
c7b0: 20 20 20 30 20 5b 3a 20 6d 73 67 3a 70 65 65 72 0 [: msg:peer
c7c0: 73 5b 5d 20 24 5b 5d 23 20 31 20 6d 61 78 20 2b s[] $[]# 1 max +
c7d0: 20 3b 5d 20 67 72 6f 75 70 23 6d 61 70 20 3b 0a ;] group#map ;.
c7e0: 0a 3a 20 77 61 69 74 2d 63 68 61 74 20 28 20 2d .: wait-chat ( -
c7f0: 2d 20 29 0a 20 20 20 20 63 68 61 74 2d 6b 65 79 - ). chat-key
c800: 73 20 5b 3a 20 40 2f 32 20 64 75 70 20 30 3d 20 s [: @/2 dup 0=
c810: 49 46 20 20 32 64 72 6f 70 20 20 45 58 49 54 20 IF 2drop EXIT
c820: 20 54 48 45 4e 0a 20 20 20 20 20 20 32 64 75 70 THEN. 2dup
c830: 20 6b 65 79 73 69 7a 65 32 20 73 61 66 65 2f 73 keysize2 safe/s
c840: 74 72 69 6e 67 20 74 75 63 6b 20 3c 69 6e 66 6f tring tuck <info
c850: 3e 20 74 79 70 65 20 49 46 20 27 2e 27 20 65 6d > type IF '.' em
c860: 69 74 20 20 54 48 45 4e 0a 20 20 20 20 20 20 2e it THEN. .
c870: 6b 65 79 2d 69 64 20 73 70 61 63 65 20 3b 5d 20 key-id space ;]
c880: 24 5b 5d 6d 61 70 0a 20 20 20 20 2e 22 20 69 73 $[]map. ." is
c890: 20 6e 6f 74 20 6f 6e 6c 69 6e 65 2e 20 70 72 65 not online. pre
c8a0: 73 73 20 6b 65 79 20 74 6f 20 72 65 63 68 65 63 ss key to rechec
c8b0: 6b 2e 22 0a 20 20 20 20 5b 3a 20 30 20 74 6f 20 k.". [: 0 to
c8c0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2d 35 36 20 74 connection -56 t
c8d0: 68 72 6f 77 20 3b 5d 20 69 73 20 64 6f 2d 64 69 hrow ;] is do-di
c8e0: 73 63 6f 6e 6e 65 63 74 0a 20 20 20 20 5b 3a 20 sconnect. [:
c8f0: 66 61 6c 73 65 20 63 68 61 74 2d 6b 65 79 73 20 false chat-keys
c900: 5b 3a 20 40 2f 32 20 6b 65 79 7c 20 70 75 62 6b [: @/2 key| pubk
c910: 65 79 20 24 40 20 6b 65 79 7c 20 73 74 72 3d 20 ey $@ key| str=
c920: 6f 72 20 3b 5d 20 24 5b 5d 6d 61 70 0a 09 49 46 or ;] $[]map..IF
c930: 20 20 62 6c 20 69 6e 73 6b 65 79 20 20 54 48 45 bl inskey THE
c940: 4e 20 20 75 70 40 20 77 61 69 74 2d 74 61 73 6b N up@ wait-task
c950: 20 21 20 3b 5d 20 69 73 20 64 6f 2d 63 6f 6e 6e ! ;] is do-conn
c960: 65 63 74 0a 20 20 20 20 77 61 69 74 2d 6b 65 79 ect. wait-key
c970: 20 63 72 20 5b 3a 20 75 70 40 20 77 61 69 74 2d cr [: up@ wait-
c980: 74 61 73 6b 20 21 20 3b 5d 20 49 53 20 64 6f 2d task ! ;] IS do-
c990: 63 6f 6e 6e 65 63 74 20 3b 0a 0a 3a 20 73 65 61 connect ;..: sea
c9a0: 72 63 68 2d 63 6f 6e 6e 65 63 74 20 28 20 6b 65 rch-connect ( ke
c9b0: 79 20 75 20 2d 2d 20 6f 2f 30 20 29 20 20 6b 65 y u -- o/0 ) ke
c9c0: 79 7c 0a 20 20 20 20 30 20 5b 3a 20 64 72 6f 70 y|. 0 [: drop
c9d0: 20 32 64 75 70 20 70 75 62 6b 65 79 20 24 40 20 2dup pubkey $@
c9e0: 6b 65 79 7c 20 73 74 72 3d 20 6f 20 61 6e 64 20 key| str= o and
c9f0: 20 64 75 70 20 30 3d 20 3b 5d 20 73 65 61 72 63 dup 0= ;] searc
ca00: 68 2d 63 6f 6e 74 65 78 74 0a 20 20 20 20 6e 69 h-context. ni
ca10: 70 20 6e 69 70 20 20 64 75 70 20 74 6f 20 63 6f p nip dup to co
ca20: 6e 6e 65 63 74 69 6f 6e 20 3b 0a 0a 3a 20 73 65 nnection ;..: se
ca30: 61 72 63 68 2d 70 65 65 72 20 28 20 2d 2d 20 63 arch-peer ( -- c
ca40: 68 61 74 20 29 0a 20 20 20 20 66 61 6c 73 65 20 hat ). false
ca50: 63 68 61 74 2d 6b 65 79 73 0a 20 20 20 20 5b 3a chat-keys. [:
ca60: 20 40 2f 32 20 6b 65 79 7c 20 72 6f 74 20 64 75 @/2 key| rot du
ca70: 70 20 30 3d 20 49 46 20 64 72 6f 70 20 73 65 61 p 0= IF drop sea
ca80: 72 63 68 2d 63 6f 6e 6e 65 63 74 0a 20 20 20 20 rch-connect.
ca90: 20 20 45 4c 53 45 20 20 6e 69 70 20 6e 69 70 20 ELSE nip nip
caa0: 20 54 48 45 4e 20 3b 5d 20 24 5b 5d 6d 61 70 20 THEN ;] $[]map
cab0: 3b 0a 0a 3a 20 6b 65 79 3e 67 72 6f 75 70 20 28 ;..: key>group (
cac0: 20 61 64 64 72 20 75 20 2d 2d 20 70 6b 20 75 20 addr u -- pk u
cad0: 29 0a 20 20 20 20 40 2f 20 32 73 77 61 70 20 74 ). @/ 2swap t
cae0: 75 63 6b 20 6d 73 67 2d 67 72 6f 75 70 24 20 24 uck msg-group$ $
caf0: 21 20 20 30 3d 0a 20 20 20 20 49 46 20 20 32 64 ! 0=. IF 2d
cb00: 75 70 20 6b 65 79 7c 20 6d 73 67 2d 67 72 6f 75 up key| msg-grou
cb10: 70 24 20 24 21 20 20 54 48 45 4e 20 3b 20 5c 20 p$ $! THEN ; \
cb20: 31 3a 31 20 63 68 61 74 2d 67 72 6f 75 70 3d 6b 1:1 chat-group=k
cb30: 65 79 0a 0a 3a 20 3f 6c 6f 61 64 2d 6d 73 67 6e ey..: ?load-msgn
cb40: 20 28 20 2d 2d 20 29 0a 20 20 20 20 6d 73 67 2d ( -- ). msg-
cb50: 67 72 6f 75 70 24 20 24 40 20 3e 67 72 6f 75 70 group$ $@ >group
cb60: 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 msg-group-o .ms
cb70: 67 3a 6c 6f 67 5b 5d 20 24 40 6c 65 6e 20 30 3d g:log[] $@len 0=
cb80: 20 49 46 0a 09 6d 73 67 2d 67 72 6f 75 70 24 20 IF..msg-group$
cb90: 24 40 20 72 6f 77 73 20 6c 6f 61 64 2d 6d 73 67 $@ rows load-msg
cba0: 6e 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 63 68 61 n THEN ;..: cha
cbb0: 74 2d 63 6f 6e 6e 65 63 74 73 20 28 20 2d 2d 20 t-connects ( --
cbc0: 29 0a 20 20 20 20 63 68 61 74 2d 6b 65 79 73 20 ). chat-keys
cbd0: 5b 3a 20 6b 65 79 3e 67 72 6f 75 70 20 3f 6c 6f [: key>group ?lo
cbe0: 61 64 2d 6d 73 67 6e 0a 20 20 20 20 20 20 64 75 ad-msgn. du
cbf0: 70 20 30 3d 20 49 46 20 20 32 64 72 6f 70 20 6d p 0= IF 2drop m
cc00: 73 67 2d 67 72 6f 75 70 24 20 24 40 20 3e 67 72 sg-group$ $@ >gr
cc10: 6f 75 70 20 20 45 58 49 54 20 20 54 48 45 4e 0a oup EXIT THEN.
cc20: 20 20 20 20 20 20 32 64 75 70 20 73 65 61 72 63 2dup searc
cc30: 68 2d 63 6f 6e 6e 65 63 74 20 3f 64 75 70 2d 49 h-connect ?dup-I
cc40: 46 20 20 3e 6f 20 2b 67 72 6f 75 70 20 67 72 65 F >o +group gre
cc50: 65 74 20 6f 3e 20 32 64 72 6f 70 20 45 58 49 54 et o> 2drop EXIT
cc60: 20 20 54 48 45 4e 0a 20 20 20 20 20 20 32 64 75 THEN. 2du
cc70: 70 20 70 6b 2d 70 65 65 6b 3f 20 20 49 46 20 20 p pk-peek? IF
cc80: 63 68 61 74 2d 63 6f 6e 6e 65 63 74 20 20 45 4c chat-connect EL
cc90: 53 45 20 20 32 64 72 6f 70 20 20 54 48 45 4e 20 SE 2drop THEN
cca0: 3b 5d 20 24 5b 5d 6d 61 70 20 3b 0a 0a 3a 20 3f ;] $[]map ;..: ?
ccb0: 77 61 69 74 2d 63 68 61 74 20 28 20 2d 2d 20 61 wait-chat ( -- a
ccc0: 64 64 72 20 75 20 29 20 23 30 2e 20 2f 63 68 61 ddr u ) #0. /cha
ccd0: 74 3a 2f 63 68 61 74 73 0a 20 20 20 20 42 45 47 t:/chats. BEG
cce0: 49 4e 20 20 63 68 61 74 73 23 20 30 3d 20 57 48 IN chats# 0= WH
ccf0: 49 4c 45 20 20 77 61 69 74 2d 63 68 61 74 20 63 ILE wait-chat c
cd00: 68 61 74 2d 63 6f 6e 6e 65 63 74 73 20 20 52 45 hat-connects RE
cd10: 50 45 41 54 0a 20 20 20 20 6d 73 67 2d 67 72 6f PEAT. msg-gro
cd20: 75 70 24 20 24 40 20 3b 20 5c 20 73 74 75 62 0a up$ $@ ; \ stub.
cd30: 0a 73 63 6f 70 65 7b 20 2f 63 68 61 74 0a 3a 6e .scope{ /chat.:n
cd40: 6f 6e 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d oname ( addr u -
cd50: 2d 20 29 0a 20 20 20 20 63 68 61 74 2d 6b 65 79 - ). chat-key
cd60: 73 20 24 5b 5d 6f 66 66 20 6e 69 63 6b 3e 63 68 s $[]off nick>ch
cd70: 61 74 20 30 20 63 68 61 74 2d 6b 65 79 73 20 24 at 0 chat-keys $
cd80: 5b 5d 40 20 6b 65 79 3e 67 72 6f 75 70 0a 20 20 []@ key>group.
cd90: 20 20 6d 73 67 2d 67 72 6f 75 70 24 20 24 40 20 msg-group$ $@
cda0: 3e 67 72 6f 75 70 20 6d 73 67 2d 67 72 6f 75 70 >group msg-group
cdb0: 2d 6f 20 2e 6d 73 67 3a 70 65 65 72 73 5b 5d 20 -o .msg:peers[]
cdc0: 24 40 20 64 75 70 20 30 3d 20 49 46 20 20 32 64 $@ dup 0= IF 2d
cdd0: 72 6f 70 0a 09 6e 69 70 20 49 46 20 20 63 68 61 rop..nip IF cha
cde0: 74 2d 63 6f 6e 6e 65 63 74 73 0a 09 45 4c 53 45 t-connects..ELSE
cdf0: 20 20 2e 22 20 54 68 61 74 20 63 68 61 74 20 69 ." That chat i
ce00: 73 6e 27 74 20 61 63 74 69 76 65 22 20 66 6f 72 sn't active" for
ce10: 74 68 3a 63 72 20 20 54 48 45 4e 0a 20 20 20 20 th:cr THEN.
ce20: 45 4c 53 45 0a 09 62 6f 75 6e 64 73 20 3f 44 4f ELSE..bounds ?DO
ce30: 20 20 32 64 75 70 20 49 20 40 20 2e 70 75 62 6b 2dup I @ .pubk
ce40: 65 79 20 24 40 20 6b 65 79 32 7c 20 73 74 72 3d ey $@ key2| str=
ce50: 20 30 3d 20 57 48 49 4c 45 20 20 63 65 6c 6c 20 0= WHILE cell
ce60: 2b 4c 4f 4f 50 0a 09 20 20 20 20 32 64 72 6f 70 +LOOP.. 2drop
ce70: 20 63 68 61 74 2d 63 6f 6e 6e 65 63 74 73 20 20 chat-connects
ce80: 45 4c 53 45 20 20 55 4e 4c 4f 4f 50 20 32 64 72 ELSE UNLOOP 2dr
ce90: 6f 70 20 54 48 45 4e 0a 20 20 20 20 54 48 45 4e op THEN. THEN
cea0: 20 20 23 30 2e 20 2f 63 68 61 74 73 20 3b 20 69 #0. /chats ; i
ceb0: 73 20 2f 63 68 61 74 0a 7d 73 63 6f 70 65 0a 0a s /chat.}scope..
cec0: 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 0a also net2o-base.
ced0: 3a 20 70 75 6e 63 68 2d 61 64 64 72 2d 69 6e 64 : punch-addr-ind
cee0: 40 20 28 20 2d 2d 20 6f 20 29 0a 20 20 20 20 70 @ ( -- o ). p
cef0: 75 6e 63 68 2d 61 64 64 72 73 20 24 5b 5d 23 20 unch-addrs $[]#
cf00: 30 20 55 2b 44 4f 0a 09 49 20 70 75 6e 63 68 2d 0 U+DO..I punch-
cf10: 61 64 64 72 73 20 24 5b 5d 20 40 20 2e 68 6f 73 addrs $[] @ .hos
cf20: 74 3a 72 6f 75 74 65 20 24 40 6c 65 6e 20 49 46 t:route $@len IF
cf30: 0a 09 20 20 20 20 49 20 70 75 6e 63 68 2d 61 64 .. I punch-ad
cf40: 64 72 73 20 24 5b 5d 20 40 20 75 6e 6c 6f 6f 70 drs $[] @ unloop
cf50: 20 20 45 58 49 54 0a 09 54 48 45 4e 0a 20 20 20 EXIT..THEN.
cf60: 20 4c 4f 4f 50 20 20 30 20 70 75 6e 63 68 2d 61 LOOP 0 punch-a
cf70: 64 64 72 73 20 24 5b 5d 20 40 20 3b 0a 3a 20 72 ddrs $[] @ ;.: r
cf80: 65 63 6f 6e 6e 65 63 74 2c 20 28 20 6f 3a 63 6f econnect, ( o:co
cf90: 6e 6e 65 63 74 69 6f 6e 20 2d 2d 20 29 0a 20 20 nnection -- ).
cfa0: 20 20 5b 3a 20 70 75 6e 63 68 2d 61 64 64 72 2d [: punch-addr-
cfb0: 69 6e 64 40 20 6f 3e 61 64 64 72 20 66 6f 72 74 ind@ o>addr fort
cfc0: 68 3a 74 79 70 65 0a 20 20 20 20 20 20 70 75 62 h:type. pub
cfd0: 6b 65 79 20 24 40 20 6b 65 79 7c 20 74 75 63 6b key $@ key| tuck
cfe0: 20 66 6f 72 74 68 3a 74 79 70 65 20 66 6f 72 74 forth:type fort
cff0: 68 3a 65 6d 69 74 20 3b 5d 20 24 74 6d 70 0a 20 h:emit ;] $tmp.
d000: 20 20 20 72 65 63 6f 6e 6e 65 63 74 28 20 2e 22 reconnect( ."
d010: 20 73 65 6e 64 20 72 65 63 6f 6e 6e 65 63 74 3a send reconnect:
d020: 20 22 20 32 64 75 70 20 32 64 75 70 20 2b 20 31 " 2dup 2dup + 1
d030: 2d 20 63 40 20 31 2b 20 2d 20 2e 61 64 64 72 24 - c@ 1+ - .addr$
d040: 20 66 6f 72 74 68 3a 63 72 20 29 0a 20 20 20 20 forth:cr ).
d050: 24 2c 20 6d 73 67 2d 72 65 63 6f 6e 6e 65 63 74 $, msg-reconnect
d060: 20 3b 0a 0a 3a 20 72 65 63 6f 6e 6e 65 63 74 73 ;..: reconnects
d070: 2c 20 28 20 6f 3a 67 72 6f 75 70 20 2d 2d 20 29 , ( o:group -- )
d080: 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f . msg-group-o
d090: 20 2e 6d 73 67 3a 70 65 65 72 73 5b 5d 20 24 40 .msg:peers[] $@
d0a0: 20 63 65 6c 6c 20 73 61 66 65 2f 73 74 72 69 6e cell safe/strin
d0b0: 67 20 62 6f 75 6e 64 73 20 55 2b 44 4f 0a 09 49 g bounds U+DO..I
d0c0: 20 40 20 2e 72 65 63 6f 6e 6e 65 63 74 2c 0a 20 @ .reconnect,.
d0d0: 20 20 20 63 65 6c 6c 20 2b 4c 4f 4f 50 20 3b 0a cell +LOOP ;.
d0e0: 0a 3a 20 73 65 6e 64 2d 72 65 63 6f 6e 6e 65 63 .: send-reconnec
d0f0: 74 73 20 28 20 6f 3a 67 72 6f 75 70 20 2d 2d 20 ts ( o:group --
d100: 29 0a 20 20 20 20 6e 65 74 32 6f 2d 63 6f 64 65 ). net2o-code
d110: 20 65 78 70 65 63 74 2d 6d 73 67 0a 20 20 20 20 expect-msg.
d120: 5b 3a 20 20 6d 73 67 2d 67 72 6f 75 70 2d 6f 20 [: msg-group-o
d130: 2e 6d 73 67 3a 6e 61 6d 65 24 20 3f 64 65 73 74 .msg:name$ ?dest
d140: 70 6b 20 24 2c 20 6d 73 67 2d 6c 65 61 76 65 0a pk $, msg-leave.
d150: 09 3c 6d 73 67 20 6d 73 67 2d 73 74 61 72 74 20 .<msg msg-start
d160: 22 6c 65 66 74 22 20 24 2c 20 6d 73 67 2d 61 63 "left" $, msg-ac
d170: 74 69 6f 6e 20 6d 73 67 2d 6f 74 72 3e 0a 09 72 tion msg-otr>..r
d180: 65 63 6f 6e 6e 65 63 74 73 2c 20 3b 5d 20 5b 6d econnects, ;] [m
d190: 73 67 2c 5d 0a 20 20 20 20 65 6e 64 2d 63 6f 64 sg,]. end-cod
d1a0: 65 7c 20 3b 0a 0a 3a 20 73 65 6e 64 2d 72 65 63 e| ;..: send-rec
d1b0: 6f 6e 6e 65 63 74 31 20 28 20 6f 3a 67 72 6f 75 onnect1 ( o:grou
d1c0: 70 20 2d 2d 20 29 0a 20 20 20 20 6e 65 74 32 6f p -- ). net2o
d1d0: 2d 63 6f 64 65 20 65 78 70 65 63 74 2d 6d 73 67 -code expect-msg
d1e0: 0a 20 20 20 20 5b 3a 20 20 6d 73 67 3a 6e 61 6d . [: msg:nam
d1f0: 65 24 20 3f 64 65 73 74 70 6b 20 24 2c 20 6d 73 e$ ?destpk $, ms
d200: 67 2d 6c 65 61 76 65 0a 09 3c 6d 73 67 20 6d 73 g-leave..<msg ms
d210: 67 2d 73 74 61 72 74 20 22 6c 65 66 74 22 20 24 g-start "left" $
d220: 2c 20 6d 73 67 2d 61 63 74 69 6f 6e 20 6d 73 67 , msg-action msg
d230: 2d 6f 74 72 3e 0a 09 2e 72 65 63 6f 6e 6e 65 63 -otr>...reconnec
d240: 74 2c 20 3b 5d 20 5b 6d 73 67 2c 5d 0a 20 20 20 t, ;] [msg,].
d250: 20 65 6e 64 2d 63 6f 64 65 7c 20 3b 0a 70 72 65 end-code| ;.pre
d260: 76 69 6f 75 73 0a 0a 3a 20 73 65 6e 64 2d 72 65 vious..: send-re
d270: 63 6f 6e 6e 65 63 74 2d 78 74 20 28 20 6f 3a 67 connect-xt ( o:g
d280: 72 6f 75 70 20 78 74 20 2d 2d 20 29 20 7b 20 78 roup xt -- ) { x
d290: 74 3a 20 78 74 20 7d 0a 20 20 20 20 6d 73 67 3a t: xt }. msg:
d2a0: 70 65 65 72 73 5b 5d 20 24 40 0a 20 20 20 20 63 peers[] $@. c
d2b0: 61 73 65 0a 09 30 20 20 20 20 6f 66 20 20 64 72 ase..0 of dr
d2c0: 6f 70 20 20 65 6e 64 6f 66 0a 09 63 65 6c 6c 20 op endof..cell
d2d0: 6f 66 20 20 40 20 3e 6f 20 6f 20 74 6f 20 63 6f of @ >o o to co
d2e0: 6e 6e 65 63 74 69 6f 6e 20 78 74 20 6f 3e 20 20 nnection xt o>
d2f0: 65 6e 64 6f 66 0a 09 64 72 6f 70 20 40 20 3e 6f endof..drop @ >o
d300: 20 6f 20 74 6f 20 63 6f 6e 6e 65 63 74 69 6f 6e o to connection
d310: 20 20 73 65 6e 64 2d 72 65 63 6f 6e 6e 65 63 74 send-reconnect
d320: 73 20 6f 3e 0a 09 30 0a 20 20 20 20 65 6e 64 63 s o>..0. endc
d330: 61 73 65 20 3b 0a 3a 20 73 65 6e 64 2d 72 65 63 ase ;.: send-rec
d340: 6f 6e 6e 65 63 74 20 28 20 6f 3a 67 72 6f 75 70 onnect ( o:group
d350: 20 2d 2d 20 29 0a 20 20 20 20 5b 27 5d 20 73 65 -- ). ['] se
d360: 6e 64 2d 6c 65 61 76 65 20 73 65 6e 64 2d 72 65 nd-leave send-re
d370: 63 6f 6e 6e 65 63 74 2d 78 74 20 3b 0a 3a 20 73 connect-xt ;.: s
d380: 65 6e 64 2d 73 69 6c 65 6e 74 2d 72 65 63 6f 6e end-silent-recon
d390: 6e 65 63 74 20 28 20 6f 3a 67 72 6f 75 70 20 2d nect ( o:group -
d3a0: 2d 20 29 0a 20 20 20 20 5b 27 5d 20 73 65 6e 64 - ). ['] send
d3b0: 2d 73 69 6c 65 6e 74 2d 6c 65 61 76 65 20 73 65 -silent-leave se
d3c0: 6e 64 2d 72 65 63 6f 6e 6e 65 63 74 2d 78 74 20 nd-reconnect-xt
d3d0: 3b 0a 0a 3a 20 64 69 73 63 6f 6e 6e 65 63 74 2d ;..: disconnect-
d3e0: 67 72 6f 75 70 20 28 20 6f 3a 67 72 6f 75 70 20 group ( o:group
d3f0: 2d 2d 20 29 0a 20 20 20 20 6d 73 67 3a 70 65 65 -- ). msg:pee
d400: 72 73 5b 5d 20 67 65 74 2d 73 74 61 63 6b 20 30 rs[] get-stack 0
d410: 20 3f 44 4f 20 20 3e 6f 20 6f 20 74 6f 20 63 6f ?DO >o o to co
d420: 6e 6e 65 63 74 69 6f 6e 0a 09 64 69 73 63 6f 6e nnection..discon
d430: 6e 65 63 74 2d 6d 65 20 6f 3e 0a 20 20 20 20 4c nect-me o>. L
d440: 4f 4f 50 20 3b 0a 3a 20 64 69 73 63 6f 6e 6e 65 OOP ;.: disconne
d450: 63 74 2d 61 6c 6c 20 28 20 6f 3a 67 72 6f 75 70 ct-all ( o:group
d460: 20 2d 2d 20 29 0a 20 20 20 20 6d 73 67 3a 70 65 -- ). msg:pe
d470: 65 72 73 5b 5d 20 67 65 74 2d 73 74 61 63 6b 20 ers[] get-stack
d480: 30 20 3f 44 4f 20 20 3e 6f 20 6f 20 74 6f 20 63 0 ?DO >o o to c
d490: 6f 6e 6e 65 63 74 69 6f 6e 0a 09 73 65 6e 64 2d onnection..send-
d4a0: 6c 65 61 76 65 20 20 64 69 73 63 6f 6e 6e 65 63 leave disconnec
d4b0: 74 2d 6d 65 20 6f 3e 0a 20 20 20 20 4c 4f 4f 50 t-me o>. LOOP
d4c0: 20 3b 0a 0a 3a 20 6c 65 61 76 65 2d 63 68 61 74 ;..: leave-chat
d4d0: 20 28 20 6f 3a 67 72 6f 75 70 20 2d 2d 20 29 0a ( o:group -- ).
d4e0: 20 20 20 20 73 65 6e 64 2d 72 65 63 6f 6e 6e 65 send-reconne
d4f0: 63 74 20 64 69 73 63 6f 6e 6e 65 63 74 2d 67 72 ct disconnect-gr
d500: 6f 75 70 20 3b 0a 3a 20 73 69 6c 65 6e 74 2d 6c oup ;.: silent-l
d510: 65 61 76 65 2d 63 68 61 74 20 28 20 6f 3a 67 72 eave-chat ( o:gr
d520: 6f 75 70 20 2d 2d 20 29 0a 20 20 20 20 73 65 6e oup -- ). sen
d530: 64 2d 73 69 6c 65 6e 74 2d 72 65 63 6f 6e 6e 65 d-silent-reconne
d540: 63 74 20 64 69 73 63 6f 6e 6e 65 63 74 2d 67 72 ct disconnect-gr
d550: 6f 75 70 20 3b 0a 0a 3a 20 6c 65 61 76 65 2d 63 oup ;..: leave-c
d560: 68 61 74 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 hats ( -- ).
d570: 5b 27 5d 20 6c 65 61 76 65 2d 63 68 61 74 20 67 ['] leave-chat g
d580: 72 6f 75 70 23 6d 61 70 20 3b 0a 0a 3a 20 73 70 roup#map ;..: sp
d590: 6c 69 74 2d 6c 6f 61 64 20 28 20 6f 3a 67 72 6f lit-load ( o:gro
d5a0: 75 70 20 2d 2d 20 29 0a 20 20 20 20 6d 73 67 3a up -- ). msg:
d5b0: 70 65 65 72 73 5b 5d 20 3e 72 20 30 0a 20 20 20 peers[] >r 0.
d5c0: 20 42 45 47 49 4e 20 20 64 75 70 20 31 2b 20 72 BEGIN dup 1+ r
d5d0: 40 20 24 5b 5d 23 20 75 3c 20 20 57 48 49 4c 45 @ $[]# u< WHILE
d5e0: 0a 09 20 20 20 20 64 75 70 20 72 40 20 24 5b 5d .. dup r@ $[]
d5f0: 20 32 40 20 2e 73 65 6e 64 2d 72 65 63 6f 6e 6e 2@ .send-reconn
d600: 65 63 74 31 0a 09 20 20 20 20 31 2b 20 64 75 70 ect1.. 1+ dup
d610: 20 72 40 20 24 5b 5d 20 40 20 3e 6f 20 6f 20 74 r@ $[] @ >o o t
d620: 6f 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64 69 73 o connection dis
d630: 63 6f 6e 6e 65 63 74 2d 6d 65 20 6f 3e 0a 20 20 connect-me o>.
d640: 20 20 52 45 50 45 41 54 20 64 72 6f 70 20 72 64 REPEAT drop rd
d650: 72 6f 70 20 3b 0a 0a 73 63 6f 70 65 7b 20 2f 63 rop ;..scope{ /c
d660: 68 61 74 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 hat.:noname ( ad
d670: 64 72 20 75 20 2d 2d 20 29 20 20 32 64 72 6f 70 dr u -- ) 2drop
d680: 0a 20 20 20 20 6d 73 67 2d 67 72 6f 75 70 24 20 . msg-group$
d690: 24 40 20 3e 67 72 6f 75 70 20 6d 73 67 2d 67 72 $@ >group msg-gr
d6a0: 6f 75 70 2d 6f 20 2e 73 70 6c 69 74 2d 6c 6f 61 oup-o .split-loa
d6b0: 64 20 3b 20 69 73 20 2f 73 70 6c 69 74 0a 7d 73 d ; is /split.}s
d6c0: 63 6f 70 65 0a 0a 5c 20 63 68 61 74 20 74 6f 70 cope..\ chat top
d6d0: 6c 65 76 65 6c 0a 0a 3a 20 64 6f 2d 63 68 61 74 level..: do-chat
d6e0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 ( addr u -- ).
d6f0: 20 20 20 67 65 74 2d 6f 72 64 65 72 20 6e 3e 72 get-order n>r
d700: 0a 20 20 20 20 63 68 61 74 2d 68 69 73 74 6f 72 . chat-histor
d710: 79 20 20 5b 27 5d 20 2f 63 68 61 74 20 3e 62 6f y ['] /chat >bo
d720: 64 79 20 31 20 73 65 74 2d 6f 72 64 65 72 0a 20 dy 1 set-order.
d730: 20 20 20 6d 73 67 2d 67 72 6f 75 70 24 20 24 21 msg-group$ $!
d740: 20 63 68 61 74 2d 65 6e 74 72 79 20 5c 20 5b 27 chat-entry \ ['
d750: 5d 20 63 6d 64 28 20 3e 62 6f 64 79 20 6f 6e 0a ] cmd( >body on.
d760: 20 20 20 20 5b 3a 20 75 70 40 20 77 61 69 74 2d [: up@ wait-
d770: 74 61 73 6b 20 21 20 3b 5d 20 49 53 20 64 6f 2d task ! ;] IS do-
d780: 63 6f 6e 6e 65 63 74 0a 20 20 20 20 42 45 47 49 connect. BEGI
d790: 4e 20 20 67 65 74 2d 69 6e 70 75 74 2d 6c 69 6e N get-input-lin
d7a0: 65 0a 09 32 64 75 70 20 22 2f 62 79 65 22 20 73 e..2dup "/bye" s
d7b0: 74 72 3d 20 3e 72 20 32 64 75 70 20 22 5c 5c 62 tr= >r 2dup "\\b
d7c0: 79 65 22 20 73 74 72 3d 20 72 3e 20 6f 72 20 30 ye" str= r> or 0
d7d0: 3d 20 57 48 49 4c 45 0a 09 20 20 20 20 64 6f 2d = WHILE.. do-
d7e0: 63 68 61 74 2d 63 6d 64 3f 20 30 3d 20 49 46 20 chat-cmd? 0= IF
d7f0: 20 61 76 61 6c 61 6e 63 68 65 2d 74 65 78 74 20 avalanche-text
d800: 20 54 48 45 4e 0a 20 20 20 20 52 45 50 45 41 54 THEN. REPEAT
d810: 20 20 32 64 72 6f 70 20 6c 65 61 76 65 2d 63 68 2drop leave-ch
d820: 61 74 73 20 20 78 63 68 61 72 2d 68 69 73 74 6f ats xchar-histo
d830: 72 79 0a 20 20 20 20 6e 72 3e 20 73 65 74 2d 6f ry. nr> set-o
d840: 72 64 65 72 20 3b 0a 0a 3a 20 61 76 61 6c 61 6e rder ;..: avalan
d850: 63 68 65 2d 74 6f 20 28 20 61 64 64 72 20 75 20 che-to ( addr u
d860: 6f 3a 63 6f 6e 74 65 78 74 20 2d 2d 20 29 0a 20 o:context -- ).
d870: 20 20 20 61 76 61 6c 61 6e 63 68 65 28 20 2e 22 avalanche( ."
d880: 20 53 65 6e 64 20 61 76 61 6c 61 6e 63 68 65 20 Send avalanche
d890: 74 6f 3a 20 22 20 70 75 62 6b 65 79 20 24 40 20 to: " pubkey $@
d8a0: 6b 65 79 3e 6e 69 63 6b 20 74 79 70 65 20 73 70 key>nick type sp
d8b0: 61 63 65 20 6f 76 65 72 20 68 65 78 2e 20 63 72 ace over hex. cr
d8c0: 20 29 0a 20 20 20 20 6f 20 74 6f 20 63 6f 6e 6e ). o to conn
d8d0: 65 63 74 69 6f 6e 0a 20 20 20 20 6e 65 74 32 6f ection. net2o
d8e0: 2d 63 6f 64 65 20 65 78 70 65 63 74 2d 6d 73 67 -code expect-msg
d8f0: 20 6d 65 73 73 61 67 65 0a 20 20 20 20 6d 73 67 message. msg
d900: 2d 67 72 6f 75 70 2d 6f 20 2e 6d 73 67 3a 6e 61 -group-o .msg:na
d910: 6d 65 24 20 32 64 75 70 20 70 75 62 6b 65 79 20 me$ 2dup pubkey
d920: 24 40 20 6b 65 79 7c 20 73 74 72 3d 20 49 46 20 $@ key| str= IF
d930: 20 32 64 72 6f 70 20 20 45 4c 53 45 20 20 67 72 2drop ELSE gr
d940: 6f 75 70 2c 20 20 54 48 45 4e 0a 20 20 20 20 24 oup, THEN. $
d950: 2c 20 6e 65 73 74 73 69 67 20 65 6e 64 2d 77 69 , nestsig end-wi
d960: 74 68 0a 20 20 20 20 65 6e 64 2d 63 6f 64 65 20 th. end-code
d970: 3b 0a 0a 5c 5c 5c 0a 4c 6f 63 61 6c 20 56 61 72 ;..\\\.Local Var
d980: 69 61 62 6c 65 73 3a 0a 66 6f 72 74 68 2d 6c 6f iables:.forth-lo
d990: 63 61 6c 2d 77 6f 72 64 73 3a 0a 20 20 20 20 28 cal-words:. (
d9a0: 0a 20 20 20 20 20 28 28 22 6e 65 74 32 6f 3a 22 . (("net2o:"
d9b0: 20 22 2b 6e 65 74 32 6f 3a 22 29 20 64 65 66 69 "+net2o:") defi
d9c0: 6e 69 74 69 6f 6e 2d 73 74 61 72 74 65 72 20 28 nition-starter (
d9d0: 66 6f 6e 74 2d 6c 6f 63 6b 2d 6b 65 79 77 6f 72 font-lock-keywor
d9e0: 64 2d 66 61 63 65 20 2e 20 31 29 0a 20 20 20 20 d-face . 1).
d9f0: 20 20 22 5b 20 5c 74 5c 6e 5d 22 20 74 20 6e 61 "[ \t\n]" t na
da00: 6d 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d 66 75 me (font-lock-fu
da10: 6e 63 74 69 6f 6e 2d 6e 61 6d 65 2d 66 61 63 65 nction-name-face
da20: 20 2e 20 33 29 29 0a 20 20 20 20 20 28 22 5b 61 . 3)). ("[a
da30: 2d 7a 5c 2d 30 2d 39 5d 2b 28 22 20 69 6d 6d 65 -z\-0-9]+(" imme
da40: 64 69 61 74 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b diate (font-lock
da50: 2d 63 6f 6d 6d 65 6e 74 2d 66 61 63 65 20 2e 20 -comment-face .
da60: 31 29 0a 20 20 20 20 20 20 22 29 22 20 6e 69 6c 1). ")" nil
da70: 20 63 6f 6d 6d 65 6e 74 20 28 66 6f 6e 74 2d 6c comment (font-l
da80: 6f 63 6b 2d 63 6f 6d 6d 65 6e 74 2d 66 61 63 65 ock-comment-face
da90: 20 2e 20 31 29 29 0a 20 20 20 20 29 0a 66 6f 72 . 1)). ).for
daa0: 74 68 2d 6c 6f 63 61 6c 2d 69 6e 64 65 6e 74 2d th-local-indent-
dab0: 77 6f 72 64 73 3a 0a 20 20 20 20 28 0a 20 20 20 words:. (.
dac0: 20 20 28 28 22 6e 65 74 32 6f 3a 22 20 22 2b 6e (("net2o:" "+n
dad0: 65 74 32 6f 3a 22 29 20 28 30 20 2e 20 32 29 20 et2o:") (0 . 2)
dae0: 28 30 20 2e 20 32 29 20 6e 6f 6e 2d 69 6d 6d 65 (0 . 2) non-imme
daf0: 64 69 61 74 65 29 0a 20 20 20 20 29 0a 45 6e 64 diate). ).End
db00: 3a 0a 5b 54 48 45 4e 5d 0a :.[THEN].