Hex Artifact Content
Not logged in

Artifact c673398270c85c8d0a2f06bb89815bb27cb6ffc6:

File tools/fossil_chat.tcl part of check-in [307233d828] - Added rudimentary proxy support to fossil chat client by mjanssen on 2007-10-02 10:34:46. Also file tools/fossil_chat.tcl part of check-in [d0305b305a] - Merged mainline into my branch to get the newest application. by aku on 2007-12-05 08:07:46.

0000: 23 21 2f 68 6f 6d 65 2f 64 72 68 2f 62 69 6e 2f  #!/home/drh/bin/
0010: 74 6f 62 65 0a 23 0a 23 20 53 69 6d 70 6c 65 20  tobe.#.# Simple 
0020: 63 68 61 74 20 63 6c 69 65 6e 74 20 66 6f 72 20  chat client for 
0030: 54 63 6c 2f 54 6b 2e 0a 23 0a 70 61 63 6b 61 67  Tcl/Tk..#.packag
0040: 65 20 72 65 71 75 69 72 65 20 54 6b 0a 0a 73 65  e require Tk..se
0050: 74 20 53 45 52 56 45 52 48 4f 53 54 20 66 6f 73  t SERVERHOST fos
0060: 73 69 6c 2d 73 63 6d 2e 68 77 61 63 69 2e 63 6f  sil-scm.hwaci.co
0070: 6d 0a 23 20 73 65 74 20 53 45 52 56 45 52 48 4f  m.# set SERVERHO
0080: 53 54 20 31 32 37 2e 30 2e 30 2e 31 0a 23 73 65  ST 127.0.0.1.#se
0090: 74 20 53 45 52 56 45 52 48 4f 53 54 20 36 34 2e  t SERVERHOST 64.
00a0: 35 2e 35 33 2e 31 39 32 0a 73 65 74 20 53 45 52  5.53.192.set SER
00b0: 56 45 52 50 4f 52 54 20 38 36 31 35 0a 0a 23 20  VERPORT 8615..# 
00c0: 73 65 74 20 74 6f 20 63 6f 72 72 65 63 74 20 76  set to correct v
00d0: 61 6c 75 65 73 20 69 66 20 79 6f 75 20 68 61 76  alues if you hav
00e0: 65 20 74 6f 20 75 73 65 20 61 20 70 72 6f 78 79  e to use a proxy
00f0: 0a 73 65 74 20 50 52 4f 58 59 48 4f 53 54 20 7b  .set PROXYHOST {
0100: 7d 0a 73 65 74 20 50 52 4f 58 59 50 4f 52 54 20  }.set PROXYPORT 
0110: 7b 7d 0a 0a 23 20 53 65 74 75 70 20 74 68 65 20  {}..# Setup the 
0120: 75 73 65 72 20 69 6e 74 65 72 66 61 63 65 0a 77  user interface.w
0130: 6d 20 74 69 74 6c 65 20 2e 20 46 6f 73 73 69 6c  m title . Fossil
0140: 2d 43 68 61 74 0a 77 6d 20 69 63 6f 6e 6e 61 6d  -Chat.wm iconnam
0150: 65 20 2e 20 5b 77 6d 20 74 69 74 6c 65 20 2e 5d  e . [wm title .]
0160: 0a 0a 6d 65 6e 75 20 2e 6d 62 20 2d 74 79 70 65  ..menu .mb -type
0170: 20 6d 65 6e 75 62 61 72 0a 69 66 20 7b 24 74 63   menubar.if {$tc
0180: 6c 5f 70 6c 61 74 66 6f 72 6d 28 70 6c 61 74 66  l_platform(platf
0190: 6f 72 6d 29 3d 3d 22 75 6e 69 78 22 20 26 26 20  orm)=="unix" && 
01a0: 24 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28 6f 73  $tcl_platform(os
01b0: 29 21 3d 22 44 61 72 77 69 6e 22 7d 20 7b 0a 20  )!="Darwin"} {. 
01c0: 20 70 61 63 6b 20 2e 6d 62 20 2d 73 69 64 65 20   pack .mb -side 
01d0: 74 6f 70 20 2d 66 69 6c 6c 20 78 0a 7d 20 65 6c  top -fill x.} el
01e0: 73 65 20 7b 0a 20 20 2e 20 63 6f 6e 66 69 67 20  se {.  . config 
01f0: 2d 6d 65 6e 75 20 2e 6d 62 0a 7d 0a 2e 6d 62 20  -menu .mb.}..mb 
0200: 61 64 64 20 63 61 73 63 61 64 65 20 2d 6c 61 62  add cascade -lab
0210: 65 6c 20 46 69 6c 65 20 2d 75 6e 64 65 72 6c 69  el File -underli
0220: 6e 65 20 30 20 2d 6d 65 6e 75 20 2e 6d 62 2e 66  ne 0 -menu .mb.f
0230: 69 6c 65 0a 6d 65 6e 75 20 2e 6d 62 2e 66 69 6c  ile.menu .mb.fil
0240: 65 20 2d 74 65 61 72 6f 66 66 20 30 0a 2e 6d 62  e -tearoff 0..mb
0250: 2e 66 69 6c 65 20 61 64 64 20 63 6f 6d 6d 61 6e  .file add comman
0260: 64 20 2d 6c 61 62 65 6c 20 53 65 6e 64 20 2d 63  d -label Send -c
0270: 6f 6d 6d 61 6e 64 20 73 65 6e 64 5f 6d 65 73 73  ommand send_mess
0280: 61 67 65 0a 2e 6d 62 2e 66 69 6c 65 20 61 64 64  age..mb.file add
0290: 20 63 6f 6d 6d 61 6e 64 20 2d 6c 61 62 65 6c 20   command -label 
02a0: 7b 52 65 6d 6f 76 65 20 6f 6c 64 65 72 20 6d 65  {Remove older me
02b0: 73 73 61 67 65 73 7d 20 2d 63 6f 6d 6d 61 6e 64  ssages} -command
02c0: 20 63 6c 65 61 6e 75 70 5f 72 65 63 6f 72 64 0a   cleanup_record.
02d0: 2e 6d 62 2e 66 69 6c 65 20 61 64 64 20 73 65 70  .mb.file add sep
02e0: 61 72 61 74 6f 72 0a 2e 6d 62 2e 66 69 6c 65 20  arator..mb.file 
02f0: 61 64 64 20 63 6f 6d 6d 61 6e 64 20 2d 6c 61 62  add command -lab
0300: 65 6c 20 7b 45 78 69 74 7d 20 2d 63 6f 6d 6d 61  el {Exit} -comma
0310: 6e 64 20 65 78 69 74 0a 0a 66 72 61 6d 65 20 2e  nd exit..frame .
0320: 77 68 6f 0a 70 61 63 6b 20 2e 77 68 6f 20 2d 73  who.pack .who -s
0330: 69 64 65 20 72 69 67 68 74 20 2d 61 6e 63 68 6f  ide right -ancho
0340: 72 20 6e 20 2d 66 69 6c 6c 20 79 0a 6c 61 62 65  r n -fill y.labe
0350: 6c 20 2e 77 68 6f 2e 74 69 74 6c 65 20 2d 74 65  l .who.title -te
0360: 78 74 20 7b 55 73 65 72 73 3a 20 20 20 20 20 20  xt {Users:      
0370: 7d 0a 70 61 63 6b 20 2e 77 68 6f 2e 74 69 74 6c  }.pack .who.titl
0380: 65 20 2d 73 69 64 65 20 74 6f 70 20 2d 61 6e 63  e -side top -anc
0390: 68 6f 72 20 6e 77 0a 6c 61 62 65 6c 20 2e 77 68  hor nw.label .wh
03a0: 6f 2e 6c 69 73 74 20 2d 61 6e 63 68 6f 72 20 77  o.list -anchor w
03b0: 20 2d 6a 75 73 74 69 66 79 20 6c 65 66 74 20 2d   -justify left -
03c0: 74 65 78 74 20 7b 7d 0a 70 61 63 6b 20 2e 77 68  text {}.pack .wh
03d0: 6f 2e 6c 69 73 74 20 2d 73 69 64 65 20 74 6f 70  o.list -side top
03e0: 20 2d 61 6e 63 68 6f 72 20 6e 77 20 2d 65 78 70   -anchor nw -exp
03f0: 61 6e 64 20 31 20 2d 70 61 64 78 20 35 0a 6c 61  and 1 -padx 5.la
0400: 62 65 6c 20 2e 77 68 6f 2e 74 69 6d 65 20 2d 74  bel .who.time -t
0410: 65 78 74 20 7b 7d 20 2d 6a 75 73 74 69 66 79 20  ext {} -justify 
0420: 72 69 67 68 74 0a 70 72 6f 63 20 75 70 64 61 74  right.proc updat
0430: 65 5f 74 69 6d 65 20 7b 7d 20 7b 0a 20 20 61 66  e_time {} {.  af
0440: 74 65 72 20 31 30 30 30 20 75 70 64 61 74 65 5f  ter 1000 update_
0450: 74 69 6d 65 0a 20 20 73 65 74 20 6e 6f 77 20 5b  time.  set now [
0460: 63 6c 6f 63 6b 20 73 65 63 6f 6e 64 73 5d 0a 20  clock seconds]. 
0470: 20 73 65 74 20 74 69 6d 65 20 5b 63 6c 6f 63 6b   set time [clock
0480: 20 66 6f 72 6d 61 74 20 24 6e 6f 77 20 2d 66 6f   format $now -fo
0490: 72 6d 61 74 20 25 48 3a 25 4d 20 2d 67 6d 74 20  rmat %H:%M -gmt 
04a0: 31 5d 0a 20 20 2e 77 68 6f 2e 74 69 6d 65 20 63  1].  .who.time c
04b0: 6f 6e 66 69 67 20 2d 74 65 78 74 20 22 55 54 43  onfig -text "UTC
04c0: 3a 20 24 74 69 6d 65 22 0a 7d 0a 75 70 64 61 74  : $time".}.updat
04d0: 65 5f 74 69 6d 65 0a 70 61 63 6b 20 2e 77 68 6f  e_time.pack .who
04e0: 2e 74 69 6d 65 20 2d 73 69 64 65 20 62 6f 74 74  .time -side bott
04f0: 6f 6d 20 2d 61 6e 63 68 6f 72 20 73 77 0a 0a 66  om -anchor sw..f
0500: 72 61 6d 65 20 2e 69 6e 70 75 74 0a 70 61 63 6b  rame .input.pack
0510: 20 2e 69 6e 70 75 74 20 2d 73 69 64 65 20 62 6f   .input -side bo
0520: 74 74 6f 6d 20 2d 66 69 6c 6c 20 78 0a 74 65 78  ttom -fill x.tex
0530: 74 20 2e 69 6e 70 75 74 2e 74 20 2d 62 64 20 31  t .input.t -bd 1
0540: 20 2d 72 65 6c 69 65 66 20 73 75 6e 6b 65 6e 20   -relief sunken 
0550: 2d 62 67 20 77 68 69 74 65 20 2d 66 67 20 62 6c  -bg white -fg bl
0560: 61 63 6b 20 2d 77 69 64 74 68 20 36 30 20 2d 68  ack -width 60 -h
0570: 65 69 67 68 74 20 33 20 5c 0a 20 20 20 2d 77 72  eight 3 \.   -wr
0580: 61 70 20 77 6f 72 64 20 2d 79 73 63 72 6f 6c 6c  ap word -yscroll
0590: 63 6f 6d 6d 61 6e 64 20 5b 6c 69 73 74 20 2e 69  command [list .i
05a0: 6e 70 75 74 2e 73 62 20 73 65 74 5d 20 2d 74 61  nput.sb set] -ta
05b0: 6b 65 66 6f 63 75 73 20 31 0a 62 69 6e 64 20 2e  kefocus 1.bind .
05c0: 69 6e 70 75 74 2e 74 20 3c 4b 65 79 2d 52 65 74  input.t <Key-Ret
05d0: 75 72 6e 3e 20 7b 73 65 6e 64 5f 6d 65 73 73 61  urn> {send_messa
05e0: 67 65 3b 20 62 72 65 61 6b 7d 0a 70 61 63 6b 20  ge; break}.pack 
05f0: 2e 69 6e 70 75 74 2e 74 20 2d 73 69 64 65 20 6c  .input.t -side l
0600: 65 66 74 20 2d 66 69 6c 6c 20 62 6f 74 68 20 2d  eft -fill both -
0610: 65 78 70 61 6e 64 20 31 0a 73 63 72 6f 6c 6c 62  expand 1.scrollb
0620: 61 72 20 2e 69 6e 70 75 74 2e 73 62 20 2d 6f 72  ar .input.sb -or
0630: 69 65 6e 74 20 76 65 72 74 69 63 61 6c 20 2d 63  ient vertical -c
0640: 6f 6d 6d 61 6e 64 20 5b 6c 69 73 74 20 2e 69 6e  ommand [list .in
0650: 70 75 74 2e 74 20 79 76 69 65 77 5d 0a 70 61 63  put.t yview].pac
0660: 6b 20 2e 69 6e 70 75 74 2e 73 62 20 2d 73 69 64  k .input.sb -sid
0670: 65 20 6c 65 66 74 20 2d 66 69 6c 6c 20 79 0a 0a  e left -fill y..
0680: 66 72 61 6d 65 20 2e 6d 73 67 0a 70 61 63 6b 20  frame .msg.pack 
0690: 2e 6d 73 67 20 2d 73 69 64 65 20 74 6f 70 20 2d  .msg -side top -
06a0: 66 69 6c 6c 20 62 6f 74 68 20 2d 65 78 70 61 6e  fill both -expan
06b0: 64 20 31 0a 74 65 78 74 20 2e 6d 73 67 2e 74 20  d 1.text .msg.t 
06c0: 2d 62 64 20 31 20 2d 72 65 6c 69 65 66 20 73 75  -bd 1 -relief su
06d0: 6e 6b 65 6e 20 2d 62 67 20 77 68 69 74 65 20 2d  nken -bg white -
06e0: 66 67 20 62 6c 61 63 6b 20 2d 77 69 64 74 68 20  fg black -width 
06f0: 36 30 20 2d 68 65 69 67 68 74 20 32 30 20 5c 0a  60 -height 20 \.
0700: 20 20 20 2d 77 72 61 70 20 77 6f 72 64 20 2d 79     -wrap word -y
0710: 73 63 72 6f 6c 6c 63 6f 6d 6d 61 6e 64 20 5b 6c  scrollcommand [l
0720: 69 73 74 20 2e 6d 73 67 2e 73 62 20 73 65 74 5d  ist .msg.sb set]
0730: 20 2d 74 61 6b 65 66 6f 63 75 73 20 30 0a 62 69   -takefocus 0.bi
0740: 6e 64 74 61 67 73 20 2e 6d 73 67 2e 74 20 5b 6c  ndtags .msg.t [l
0750: 69 73 74 20 2e 6d 73 67 2e 74 20 2e 20 61 6c 6c  ist .msg.t . all
0760: 5d 0a 2e 6d 73 67 2e 74 20 74 61 67 20 63 6f 6e  ]..msg.t tag con
0770: 66 69 67 20 65 72 72 6f 72 20 2d 66 6f 72 65 67  fig error -foreg
0780: 72 6f 75 6e 64 20 72 65 64 0a 2e 6d 73 67 2e 74  round red..msg.t
0790: 20 74 61 67 20 63 6f 6e 66 69 67 20 6d 65 74 61   tag config meta
07a0: 20 2d 66 6f 72 65 67 72 6f 75 6e 64 20 66 6f 72   -foreground for
07b0: 65 73 74 67 72 65 65 6e 0a 2e 6d 73 67 2e 74 20  estgreen..msg.t 
07c0: 74 61 67 20 63 6f 6e 66 69 67 20 6e 6f 72 6d 20  tag config norm 
07d0: 2d 66 6f 72 65 67 72 6f 75 6e 64 20 62 6c 61 63  -foreground blac
07e0: 6b 0a 70 61 63 6b 20 2e 6d 73 67 2e 74 20 2d 73  k.pack .msg.t -s
07f0: 69 64 65 20 6c 65 66 74 20 2d 66 69 6c 6c 20 62  ide left -fill b
0800: 6f 74 68 20 2d 65 78 70 61 6e 64 20 31 0a 73 63  oth -expand 1.sc
0810: 72 6f 6c 6c 62 61 72 20 2e 6d 73 67 2e 73 62 20  rollbar .msg.sb 
0820: 2d 6f 72 69 65 6e 74 20 76 65 72 74 69 63 61 6c  -orient vertical
0830: 20 2d 63 6f 6d 6d 61 6e 64 20 5b 6c 69 73 74 20   -command [list 
0840: 2e 6d 73 67 2e 74 20 79 76 69 65 77 5d 0a 70 61  .msg.t yview].pa
0850: 63 6b 20 2e 6d 73 67 2e 73 62 20 2d 73 69 64 65  ck .msg.sb -side
0860: 20 6c 65 66 74 20 2d 66 69 6c 6c 20 79 0a 0a 75   left -fill y..u
0870: 70 64 61 74 65 0a 0a 23 20 53 65 6e 64 20 70 65  pdate..# Send pe
0880: 72 69 6f 64 69 63 20 6d 65 73 73 61 67 65 73 20  riodic messages 
0890: 74 6f 20 6b 65 65 70 20 74 68 65 20 54 43 50 2f  to keep the TCP/
08a0: 49 50 20 6c 69 6e 6b 20 75 70 0a 23 0a 70 72 6f  IP link up.#.pro
08b0: 63 20 6b 65 65 70 5f 61 6c 69 76 65 20 7b 7d 20  c keep_alive {} 
08c0: 7b 0a 20 20 67 6c 6f 62 61 6c 20 54 49 4d 45 52  {.  global TIMER
08d0: 20 53 4f 43 4b 45 54 0a 20 20 63 61 74 63 68 20   SOCKET.  catch 
08e0: 7b 61 66 74 65 72 20 63 61 6e 63 65 6c 20 24 54  {after cancel $T
08f0: 49 4d 45 52 7d 0a 20 20 73 65 74 20 54 49 4d 45  IMER}.  set TIME
0900: 52 20 5b 61 66 74 65 72 20 33 30 30 30 30 30 20  R [after 300000 
0910: 6b 65 65 70 5f 61 6c 69 76 65 5d 0a 20 20 63 61  keep_alive].  ca
0920: 74 63 68 20 7b 70 75 74 73 20 24 53 4f 43 4b 45  tch {puts $SOCKE
0930: 54 20 6e 6f 6f 70 3b 20 66 6c 75 73 68 20 24 53  T noop; flush $S
0940: 4f 43 4b 45 54 7d 0a 7d 0a 0a 23 20 43 6f 6e 6e  OCKET}.}..# Conn
0950: 65 63 74 20 74 6f 20 74 68 65 20 73 65 72 76 65  ect to the serve
0960: 72 0a 70 72 6f 63 20 63 6f 6e 6e 65 63 74 20 7b  r.proc connect {
0970: 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 53 4f 43  } {.  global SOC
0980: 4b 45 54 20 74 63 6c 5f 70 6c 61 74 66 6f 72 6d  KET tcl_platform
0990: 0a 20 20 63 61 74 63 68 20 7b 63 6c 6f 73 65 20  .  catch {close 
09a0: 24 53 4f 43 4b 45 54 7d 0a 20 20 69 66 20 7b 5b  $SOCKET}.  if {[
09b0: 63 61 74 63 68 20 7b 0a 20 20 20 20 20 20 69 66  catch {.      if
09c0: 20 7b 24 3a 3a 50 52 4f 58 59 48 4f 53 54 20 6e   {$::PROXYHOST n
09d0: 65 20 7b 7d 7d 20 7b 0a 20 20 20 20 20 20 20 20  e {}} {.        
09e0: 20 20 73 65 74 20 53 4f 43 4b 45 54 20 5b 73 6f    set SOCKET [so
09f0: 63 6b 65 74 20 24 3a 3a 50 52 4f 58 59 48 4f 53  cket $::PROXYHOS
0a00: 54 20 24 3a 3a 50 52 4f 58 59 50 4f 52 54 5d 0a  T $::PROXYPORT].
0a10: 20 20 20 20 20 20 20 20 20 20 70 75 74 73 20 24            puts $
0a20: 53 4f 43 4b 45 54 20 22 43 4f 4e 4e 45 43 54 20  SOCKET "CONNECT 
0a30: 24 3a 3a 53 45 52 56 45 52 48 4f 53 54 3a 24 3a  $::SERVERHOST:$:
0a40: 3a 53 45 52 56 45 52 50 4f 52 54 20 48 54 54 50  :SERVERPORT HTTP
0a50: 2f 31 2e 31 22 0a 20 20 20 20 20 20 20 20 20 20  /1.1".          
0a60: 70 75 74 73 20 24 53 4f 43 4b 45 54 20 22 48 6f  puts $SOCKET "Ho
0a70: 73 74 3a 20 20 24 3a 3a 53 45 52 56 45 52 48 4f  st:  $::SERVERHO
0a80: 53 54 3a 24 3a 3a 53 45 52 56 45 52 50 4f 52 54  ST:$::SERVERPORT
0a90: 22 20 0a 20 20 20 20 20 20 20 20 20 20 70 75 74  " .          put
0aa0: 73 20 24 53 4f 43 4b 45 54 20 22 22 0a 20 20 20  s $SOCKET "".   
0ab0: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
0ac0: 20 20 20 20 20 20 73 65 74 20 53 4f 43 4b 45 54        set SOCKET
0ad0: 20 5b 73 6f 63 6b 65 74 20 24 3a 3a 53 45 52 56   [socket $::SERV
0ae0: 45 52 48 4f 53 54 20 24 3a 3a 53 45 52 56 45 52  ERHOST $::SERVER
0af0: 50 4f 52 54 5d 0a 20 20 20 20 20 20 7d 0a 20 20  PORT].      }.  
0b00: 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 53 4f    fconfigure $SO
0b10: 43 4b 45 54 20 2d 74 72 61 6e 73 6c 61 74 69 6f  CKET -translatio
0b20: 6e 20 62 69 6e 61 72 79 20 2d 62 6c 6f 63 6b 69  n binary -blocki
0b30: 6e 67 20 30 0a 20 20 20 20 70 75 74 73 20 24 53  ng 0.    puts $S
0b40: 4f 43 4b 45 54 20 5b 6c 69 73 74 20 6c 6f 67 69  OCKET [list logi
0b50: 6e 20 24 74 63 6c 5f 70 6c 61 74 66 6f 72 6d 28  n $tcl_platform(
0b60: 75 73 65 72 29 20 66 61 63 74 2c 66 75 7a 7a 5d  user) fact,fuzz]
0b70: 0a 20 20 20 20 66 6c 75 73 68 20 24 53 4f 43 4b  .    flush $SOCK
0b80: 45 54 0a 20 20 20 20 66 69 6c 65 65 76 65 6e 74  ET.    fileevent
0b90: 20 24 53 4f 43 4b 45 54 20 72 65 61 64 61 62 6c   $SOCKET readabl
0ba0: 65 20 68 61 6e 64 6c 65 5f 69 6e 70 75 74 0a 20  e handle_input. 
0bb0: 20 20 20 6b 65 65 70 5f 61 6c 69 76 65 0a 20 20     keep_alive.  
0bc0: 7d 20 65 72 72 6d 73 67 5d 7d 20 7b 0a 20 20 20  } errmsg]} {.   
0bd0: 20 69 66 20 7b 5b 74 6b 5f 6d 65 73 73 61 67 65   if {[tk_message
0be0: 42 6f 78 20 2d 69 63 6f 6e 20 65 72 72 6f 72 20  Box -icon error 
0bf0: 2d 74 79 70 65 20 79 65 73 6e 6f 20 2d 70 61 72  -type yesno -par
0c00: 65 6e 74 20 2e 20 2d 6d 65 73 73 61 67 65 20 5c  ent . -message \
0c10: 0a 20 20 20 20 20 20 20 20 20 20 20 22 55 6e 61  .           "Una
0c20: 62 6c 65 20 74 6f 20 63 6f 6e 6e 65 63 74 20 74  ble to connect t
0c30: 6f 20 73 65 72 76 65 72 2e 20 20 24 65 72 72 6d  o server.  $errm
0c40: 73 67 2e 5c 6e 5c 6e 54 72 79 20 61 67 61 69 6e  sg.\n\nTry again
0c50: 3f 22 5d 3d 3d 22 79 65 73 22 7d 20 7b 0a 20 20  ?"]=="yes"} {.  
0c60: 20 20 20 20 61 66 74 65 72 20 31 30 30 20 63 6f      after 100 co
0c70: 6e 6e 65 63 74 0a 20 20 20 20 7d 0a 20 20 7d 0a  nnect.    }.  }.
0c80: 7d 0a 63 6f 6e 6e 65 63 74 0a 0a 23 20 53 65 6e  }.connect..# Sen
0c90: 64 20 74 68 65 20 6d 65 73 73 61 67 65 20 74 65  d the message te
0ca0: 78 74 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20  xt contained in 
0cb0: 74 68 65 20 2e 69 6e 70 75 74 2e 74 20 77 69 64  the .input.t wid
0cc0: 67 65 74 20 74 6f 20 74 68 65 20 73 65 72 76 65  get to the serve
0cd0: 72 2e 0a 23 0a 70 72 6f 63 20 73 65 6e 64 5f 6d  r..#.proc send_m
0ce0: 65 73 73 61 67 65 20 7b 7d 20 7b 0a 20 20 73 65  essage {} {.  se
0cf0: 74 20 74 78 74 20 5b 2e 69 6e 70 75 74 2e 74 20  t txt [.input.t 
0d00: 67 65 74 20 31 2e 30 20 65 6e 64 5d 0a 20 20 2e  get 1.0 end].  .
0d10: 69 6e 70 75 74 2e 74 20 64 65 6c 65 74 65 20 31  input.t delete 1
0d20: 2e 30 20 65 6e 64 0a 20 20 72 65 67 73 75 62 20  .0 end.  regsub 
0d30: 2d 61 6c 6c 20 22 5c 5b 20 5c 74 5c 6e 5c 66 5c  -all "\[ \t\n\f\
0d40: 72 5c 5d 2b 22 20 5b 73 74 72 69 6e 67 20 74 72  r\]+" [string tr
0d50: 69 6d 20 24 74 78 74 5d 20 7b 20 7d 20 74 78 74  im $txt] { } txt
0d60: 0a 20 20 69 66 20 7b 24 74 78 74 3d 3d 22 22 7d  .  if {$txt==""}
0d70: 20 72 65 74 75 72 6e 0a 20 20 67 6c 6f 62 61 6c   return.  global
0d80: 20 53 4f 43 4b 45 54 0a 20 20 70 75 74 73 20 24   SOCKET.  puts $
0d90: 53 4f 43 4b 45 54 20 5b 6c 69 73 74 20 6d 65 73  SOCKET [list mes
0da0: 73 61 67 65 20 24 74 78 74 5d 0a 20 20 66 6c 75  sage $txt].  flu
0db0: 73 68 20 24 53 4f 43 4b 45 54 0a 7d 0a 0a 2e 6d  sh $SOCKET.}...m
0dc0: 62 20 61 64 64 20 63 61 73 63 61 64 65 20 2d 6c  b add cascade -l
0dd0: 61 62 65 6c 20 22 54 72 61 6e 73 66 65 72 22 20  abel "Transfer" 
0de0: 2d 75 6e 64 65 72 6c 69 6e 65 20 30 20 2d 6d 65  -underline 0 -me
0df0: 6e 75 20 2e 6d 62 2e 66 69 6c 65 73 0a 6d 65 6e  nu .mb.files.men
0e00: 75 20 2e 6d 62 2e 66 69 6c 65 73 20 2d 74 65 61  u .mb.files -tea
0e10: 72 6f 66 66 20 30 0a 2e 6d 62 2e 66 69 6c 65 73  roff 0..mb.files
0e20: 20 61 64 64 20 63 6f 6d 6d 61 6e 64 20 2d 6c 61   add command -la
0e30: 62 65 6c 20 22 53 65 6e 64 20 66 69 6c 65 2e 2e  bel "Send file..
0e40: 2e 22 20 2d 63 6f 6d 6d 61 6e 64 20 73 65 6e 64  ." -command send
0e50: 5f 66 69 6c 65 0a 2e 6d 62 2e 66 69 6c 65 73 20  _file..mb.files 
0e60: 61 64 64 20 63 6f 6d 6d 61 6e 64 20 2d 6c 61 62  add command -lab
0e70: 65 6c 20 22 44 65 6c 65 74 65 20 66 69 6c 65 73  el "Delete files
0e80: 22 20 2d 63 6f 6d 6d 61 6e 64 20 64 65 6c 65 74  " -command delet
0e90: 65 5f 66 69 6c 65 73 20 5c 0a 20 20 20 20 2d 73  e_files \.    -s
0ea0: 74 61 74 65 20 64 69 73 61 62 6c 65 64 0a 2e 6d  tate disabled..m
0eb0: 62 2e 66 69 6c 65 73 20 61 64 64 20 73 65 70 61  b.files add sepa
0ec0: 72 61 74 6f 72 0a 0a 23 20 45 6e 63 6f 64 65 20  rator..# Encode 
0ed0: 61 20 73 74 72 69 6e 67 20 28 70 6f 73 73 69 62  a string (possib
0ee0: 6c 79 20 63 6f 6e 74 61 69 6e 69 6e 67 20 62 69  ly containing bi
0ef0: 6e 61 72 79 20 61 6e 64 20 5c 30 30 30 20 63 68  nary and \000 ch
0f00: 61 72 61 63 74 65 72 73 29 20 69 6e 74 6f 0a 23  aracters) into.#
0f10: 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20   single line of 
0f20: 74 65 78 74 2e 0a 23 0a 70 72 6f 63 20 65 6e 63  text..#.proc enc
0f30: 6f 64 65 20 7b 74 78 74 7d 20 7b 0a 20 20 72 65  ode {txt} {.  re
0f40: 74 75 72 6e 20 5b 73 74 72 69 6e 67 20 6d 61 70  turn [string map
0f50: 20 5b 6c 69 73 74 20 25 20 25 32 35 20 2b 20 25   [list % %25 + %
0f60: 32 62 20 22 20 22 20 2b 20 5c 6e 20 25 30 61 20  2b " " + \n %0a 
0f70: 5c 74 20 25 30 39 20 5c 30 30 30 20 25 30 30 5d  \t %09 \000 %00]
0f80: 20 24 74 78 74 5d 0a 7d 0a 0a 23 20 55 6e 64 6f   $txt].}..# Undo
0f90: 20 74 68 65 20 77 6f 72 6b 20 6f 66 20 65 6e 63   the work of enc
0fa0: 6f 64 65 2e 20 20 43 6f 6e 76 65 72 74 20 61 6e  ode.  Convert an
0fb0: 20 65 6e 63 6f 64 65 64 20 73 74 72 69 6e 67 20   encoded string 
0fc0: 62 61 63 6b 20 69 6e 74 6f 20 69 74 73 20 6f 72  back into its or
0fd0: 69 67 69 6e 61 6c 0a 23 20 66 6f 72 6d 2e 0a 23  iginal.# form..#
0fe0: 0a 70 72 6f 63 20 64 65 63 6f 64 65 20 7b 74 78  .proc decode {tx
0ff0: 74 7d 20 7b 0a 20 20 72 65 74 75 72 6e 20 5b 73  t} {.  return [s
1000: 74 72 69 6e 67 20 6d 61 70 20 5b 6c 69 73 74 20  tring map [list 
1010: 25 30 30 20 5c 30 30 30 20 25 30 39 20 5c 74 20  %00 \000 %09 \t 
1020: 25 30 61 20 5c 6e 20 2b 20 22 20 22 20 25 32 62  %0a \n + " " %2b
1030: 20 2b 20 25 32 35 20 25 5d 20 24 74 78 74 5d 0a   + %25 %] $txt].
1040: 7d 0a 0a 23 20 44 65 6c 65 74 65 20 61 6c 6c 20  }..# Delete all 
1050: 6f 66 20 74 68 65 20 64 6f 77 6e 6c 6f 61 64 65  of the downloade
1060: 64 20 66 69 6c 65 73 20 77 65 20 61 72 65 20 63  d files we are c
1070: 75 72 72 65 6e 74 6c 79 20 68 6f 6c 64 69 6e 67  urrently holding
1080: 2e 0a 23 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f  ..#.proc delete_
1090: 66 69 6c 65 73 20 7b 7d 20 7b 0a 20 20 67 6c 6f  files {} {.  glo
10a0: 62 61 6c 20 46 49 4c 45 53 0a 20 20 2e 6d 62 2e  bal FILES.  .mb.
10b0: 66 69 6c 65 73 20 64 65 6c 65 74 65 20 33 20 65  files delete 3 e
10c0: 6e 64 0a 20 20 61 72 72 61 79 20 75 6e 73 65 74  nd.  array unset
10d0: 20 46 49 4c 45 53 0a 20 20 2e 6d 62 2e 66 69 6c   FILES.  .mb.fil
10e0: 65 73 20 65 6e 74 72 79 63 6f 6e 66 69 67 75 72  es entryconfigur
10f0: 65 20 31 20 2d 73 74 61 74 65 20 64 69 73 61 62  e 1 -state disab
1100: 6c 65 64 20 0a 7d 0a 0a 23 20 50 72 6f 6d 70 74  led .}..# Prompt
1110: 20 74 68 65 20 75 73 65 72 20 74 6f 20 73 65 6c   the user to sel
1120: 65 63 74 20 61 20 66 69 6c 65 20 66 72 6f 6d 20  ect a file from 
1130: 74 68 65 20 64 69 73 6b 2e 20 20 54 68 65 6e 20  the disk.  Then 
1140: 73 65 6e 64 20 74 68 61 74 0a 23 20 66 69 6c 65  send that.# file
1150: 20 74 6f 20 61 6c 6c 20 63 68 61 74 20 70 61 72   to all chat par
1160: 74 69 63 69 70 61 6e 74 73 2e 0a 23 0a 70 72 6f  ticipants..#.pro
1170: 63 20 73 65 6e 64 5f 66 69 6c 65 20 7b 7d 20 7b  c send_file {} {
1180: 0a 20 20 67 6c 6f 62 61 6c 20 53 4f 43 4b 45 54  .  global SOCKET
1190: 0a 20 20 73 65 74 20 6f 70 65 6e 66 69 6c 65 20  .  set openfile 
11a0: 5b 74 6b 5f 67 65 74 4f 70 65 6e 46 69 6c 65 5d  [tk_getOpenFile]
11b0: 0a 20 20 69 66 20 7b 24 6f 70 65 6e 66 69 6c 65  .  if {$openfile
11c0: 3d 3d 22 22 7d 20 72 65 74 75 72 6e 0a 20 20 73  ==""} return.  s
11d0: 65 74 20 66 20 5b 6f 70 65 6e 20 24 6f 70 65 6e  et f [open $open
11e0: 66 69 6c 65 5d 0a 20 20 66 63 6f 6e 66 69 67 75  file].  fconfigu
11f0: 72 65 20 24 66 20 2d 74 72 61 6e 73 6c 61 74 69  re $f -translati
1200: 6f 6e 20 62 69 6e 61 72 79 0a 20 20 73 65 74 20  on binary.  set 
1210: 64 61 74 61 20 5b 72 65 61 64 20 24 66 5d 0a 20  data [read $f]. 
1220: 20 63 6c 6f 73 65 20 24 66 0a 20 20 70 75 74 73   close $f.  puts
1230: 20 24 53 4f 43 4b 45 54 20 5b 6c 69 73 74 20 66   $SOCKET [list f
1240: 69 6c 65 20 5b 66 69 6c 65 20 74 61 69 6c 20 24  ile [file tail $
1250: 6f 70 65 6e 66 69 6c 65 5d 20 5b 65 6e 63 6f 64  openfile] [encod
1260: 65 20 24 64 61 74 61 5d 5d 0a 20 20 66 6c 75 73  e $data]].  flus
1270: 68 20 24 53 4f 43 4b 45 54 0a 20 20 73 65 74 20  h $SOCKET.  set 
1280: 74 69 6d 65 20 5b 63 6c 6f 63 6b 20 66 6f 72 6d  time [clock form
1290: 61 74 20 5b 63 6c 6f 63 6b 20 73 65 63 6f 6e 64  at [clock second
12a0: 73 5d 20 2d 66 6f 72 6d 61 74 20 7b 25 48 3a 25  s] -format {%H:%
12b0: 4d 7d 20 2d 67 6d 74 20 31 5d 0a 20 20 2e 6d 73  M} -gmt 1].  .ms
12c0: 67 2e 74 20 69 6e 73 65 72 74 20 65 6e 64 20 22  g.t insert end "
12d0: 5c 5b 24 74 69 6d 65 5c 5d 20 73 65 6e 74 20 66  \[$time\] sent f
12e0: 69 6c 65 20 5b 66 69 6c 65 20 74 61 69 6c 20 24  ile [file tail $
12f0: 6f 70 65 6e 66 69 6c 65 5d 5c 0a 20 20 20 20 20  openfile]\.     
1300: 20 20 20 2d 20 5b 73 74 72 69 6e 67 20 6c 65 6e     - [string len
1310: 67 74 68 20 24 64 61 74 61 5d 20 62 79 74 65 73  gth $data] bytes
1320: 5c 6e 22 20 6d 65 74 61 0a 20 20 2e 6d 73 67 2e  \n" meta.  .msg.
1330: 74 20 73 65 65 20 65 6e 64 0a 7d 0a 0a 23 20 53  t see end.}..# S
1340: 61 76 65 20 74 68 65 20 6e 61 6d 65 64 20 66 69  ave the named fi
1350: 6c 65 20 74 6f 20 74 68 65 20 64 69 73 6b 2e 0a  le to the disk..
1360: 23 0a 20 70 72 6f 63 20 73 61 76 65 5f 66 69 6c  #. proc save_fil
1370: 65 20 7b 66 69 6c 65 6e 61 6d 65 7d 20 7b 0a 20  e {filename} {. 
1380: 20 67 6c 6f 62 61 6c 20 46 49 4c 45 53 0a 20 20   global FILES.  
1390: 73 65 74 20 73 61 76 65 66 69 6c 65 20 5b 74 6b  set savefile [tk
13a0: 5f 67 65 74 53 61 76 65 46 69 6c 65 20 2d 69 6e  _getSaveFile -in
13b0: 69 74 69 61 6c 66 69 6c 65 20 24 66 69 6c 65 6e  itialfile $filen
13c0: 61 6d 65 5d 0a 20 20 69 66 20 7b 24 73 61 76 65  ame].  if {$save
13d0: 66 69 6c 65 3d 3d 22 22 7d 20 72 65 74 75 72 6e  file==""} return
13e0: 0a 20 20 73 65 74 20 66 20 5b 6f 70 65 6e 20 24  .  set f [open $
13f0: 73 61 76 65 66 69 6c 65 20 77 5d 0a 20 20 66 63  savefile w].  fc
1400: 6f 6e 66 69 67 75 72 65 20 24 66 20 2d 74 72 61  onfigure $f -tra
1410: 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72 79 0a  nslation binary.
1420: 20 20 70 75 74 73 20 2d 6e 6f 6e 65 77 6c 69 6e    puts -nonewlin
1430: 65 20 24 66 20 5b 64 65 63 6f 64 65 20 24 46 49  e $f [decode $FI
1440: 4c 45 53 28 24 66 69 6c 65 6e 61 6d 65 29 5d 0a  LES($filename)].
1450: 20 20 63 6c 6f 73 65 20 24 66 0a 7d 0a 0a 23 20    close $f.}..# 
1460: 48 61 6e 64 6c 65 20 61 20 22 66 69 6c 65 22 20  Handle a "file" 
1470: 6d 65 73 73 61 67 65 20 66 72 6f 6d 20 74 68 65  message from the
1480: 20 63 68 61 74 20 73 65 72 76 65 72 2e 0a 23 0a   chat server..#.
1490: 70 72 6f 63 20 68 61 6e 64 6c 65 5f 66 69 6c 65  proc handle_file
14a0: 20 7b 66 72 6f 6d 20 66 69 6c 65 6e 61 6d 65 20   {from filename 
14b0: 64 61 74 61 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c  data} {.  global
14c0: 20 46 49 4c 45 53 0a 20 20 66 6f 72 65 61 63 68   FILES.  foreach
14d0: 20 70 72 69 6f 72 20 5b 61 72 72 61 79 20 6e 61   prior [array na
14e0: 6d 65 73 20 46 49 4c 45 53 5d 20 7b 0a 20 20 20  mes FILES] {.   
14f0: 20 69 66 20 7b 24 66 69 6c 65 6e 61 6d 65 3d 3d   if {$filename==
1500: 24 70 72 69 6f 72 7d 20 62 72 65 61 6b 0a 20 20  $prior} break.  
1510: 7d 0a 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65  }.  if {![info e
1520: 78 69 73 74 73 20 70 72 69 6f 72 5d 20 7c 7c 20  xists prior] || 
1530: 24 66 69 6c 65 6e 61 6d 65 21 3d 24 70 72 69 6f  $filename!=$prio
1540: 72 7d 20 7b 0a 20 20 20 20 2e 6d 62 2e 66 69 6c  r} {.    .mb.fil
1550: 65 73 20 61 64 64 20 63 6f 6d 6d 61 6e 64 20 2d  es add command -
1560: 6c 61 62 65 6c 20 22 53 61 76 65 20 5c 22 24 66  label "Save \"$f
1570: 69 6c 65 6e 61 6d 65 5c 22 22 20 5c 0a 20 20 20  ilename\"" \.   
1580: 20 20 20 20 20 2d 63 6f 6d 6d 61 6e 64 20 5b 6c       -command [l
1590: 69 73 74 20 73 61 76 65 5f 66 69 6c 65 20 24 66  ist save_file $f
15a0: 69 6c 65 6e 61 6d 65 5d 0a 20 20 7d 0a 20 20 73  ilename].  }.  s
15b0: 65 74 20 46 49 4c 45 53 28 24 66 69 6c 65 6e 61  et FILES($filena
15c0: 6d 65 29 20 24 64 61 74 61 0a 20 20 2e 6d 62 2e  me) $data.  .mb.
15d0: 66 69 6c 65 73 20 65 6e 74 72 79 63 6f 6e 66 69  files entryconfi
15e0: 67 75 72 65 20 31 20 2d 73 74 61 74 65 20 61 63  gure 1 -state ac
15f0: 74 69 76 65 20 0a 20 20 73 65 74 20 74 69 6d 65  tive .  set time
1600: 20 5b 63 6c 6f 63 6b 20 66 6f 72 6d 61 74 20 5b   [clock format [
1610: 63 6c 6f 63 6b 20 73 65 63 6f 6e 64 73 5d 20 2d  clock seconds] -
1620: 66 6f 72 6d 61 74 20 7b 25 48 3a 25 4d 7d 20 2d  format {%H:%M} -
1630: 67 6d 74 20 31 5d 0a 20 20 2e 6d 73 67 2e 74 20  gmt 1].  .msg.t 
1640: 69 6e 73 65 72 74 20 65 6e 64 20 22 5c 5b 24 74  insert end "\[$t
1650: 69 6d 65 20 24 66 72 6f 6d 5c 5d 20 22 20 6d 65  ime $from\] " me
1660: 74 61 20 22 46 69 6c 65 3a 20 5c 22 24 66 69 6c  ta "File: \"$fil
1670: 65 6e 61 6d 65 5c 22 5c 6e 22 20 6e 6f 72 6d 0a  ename\"\n" norm.
1680: 20 20 2e 6d 73 67 2e 74 20 73 65 65 20 65 6e 64    .msg.t see end
1690: 0a 7d 0a 0a 23 20 48 61 6e 64 6c 65 20 69 6e 70  .}..# Handle inp
16a0: 75 74 20 66 72 6f 6d 20 74 68 65 20 73 65 72 76  ut from the serv
16b0: 65 72 0a 23 0a 70 72 6f 63 20 68 61 6e 64 6c 65  er.#.proc handle
16c0: 5f 69 6e 70 75 74 20 7b 7d 20 7b 0a 20 20 67 6c  _input {} {.  gl
16d0: 6f 62 61 6c 20 53 4f 43 4b 45 54 0a 20 20 69 66  obal SOCKET.  if
16e0: 20 7b 5b 65 6f 66 20 24 53 4f 43 4b 45 54 5d 7d   {[eof $SOCKET]}
16f0: 20 7b 0a 20 20 20 20 64 69 73 63 6f 6e 6e 65 63   {.    disconnec
1700: 74 0a 20 20 20 20 72 65 74 75 72 6e 0a 20 20 7d  t.    return.  }
1710: 0a 20 20 73 65 74 20 6c 69 6e 65 20 5b 67 65 74  .  set line [get
1720: 73 20 24 53 4f 43 4b 45 54 5d 0a 20 20 69 66 20  s $SOCKET].  if 
1730: 7b 24 6c 69 6e 65 3d 3d 22 22 7d 20 72 65 74 75  {$line==""} retu
1740: 72 6e 0a 20 20 73 65 74 20 63 6d 64 20 5b 6c 69  rn.  set cmd [li
1750: 6e 64 65 78 20 24 6c 69 6e 65 20 30 5d 0a 20 20  ndex $line 0].  
1760: 69 66 20 7b 24 63 6d 64 3d 3d 22 75 73 65 72 6c  if {$cmd=="userl
1770: 69 73 74 22 7d 20 7b 0a 20 20 20 20 73 65 74 20  ist"} {.    set 
1780: 75 6c 69 73 74 20 7b 7d 0a 20 20 20 20 66 6f 72  ulist {}.    for
1790: 65 61 63 68 20 75 20 5b 6c 72 61 6e 67 65 20 24  each u [lrange $
17a0: 6c 69 6e 65 20 31 20 65 6e 64 5d 20 7b 0a 20 20  line 1 end] {.  
17b0: 20 20 20 20 61 70 70 65 6e 64 20 75 6c 69 73 74      append ulist
17c0: 20 24 75 5c 6e 0a 20 20 20 20 7d 0a 20 20 20 20   $u\n.    }.    
17d0: 2e 77 68 6f 2e 6c 69 73 74 20 63 6f 6e 66 69 67  .who.list config
17e0: 20 2d 74 65 78 74 20 5b 73 74 72 69 6e 67 20 74   -text [string t
17f0: 72 69 6d 20 24 75 6c 69 73 74 5d 0a 20 20 7d 20  rim $ulist].  } 
1800: 65 6c 73 65 69 66 20 7b 24 63 6d 64 3d 3d 22 6d  elseif {$cmd=="m
1810: 65 73 73 61 67 65 22 7d 20 7b 0a 20 20 20 20 73  essage"} {.    s
1820: 65 74 20 74 69 6d 65 20 5b 63 6c 6f 63 6b 20 66  et time [clock f
1830: 6f 72 6d 61 74 20 5b 63 6c 6f 63 6b 20 73 65 63  ormat [clock sec
1840: 6f 6e 64 73 5d 20 2d 66 6f 72 6d 61 74 20 7b 25  onds] -format {%
1850: 48 3a 25 4d 7d 20 2d 67 6d 74 20 31 5d 0a 20 20  H:%M} -gmt 1].  
1860: 20 20 73 65 74 20 66 72 6f 6d 20 5b 6c 69 6e 64    set from [lind
1870: 65 78 20 24 6c 69 6e 65 20 31 5d 0a 20 20 20 20  ex $line 1].    
1880: 2e 6d 73 67 2e 74 20 69 6e 73 65 72 74 20 65 6e  .msg.t insert en
1890: 64 20 22 5c 5b 24 74 69 6d 65 20 24 66 72 6f 6d  d "\[$time $from
18a0: 5c 5d 20 22 20 6d 65 74 61 20 5b 6c 69 6e 64 65  \] " meta [linde
18b0: 78 20 24 6c 69 6e 65 20 32 5d 5c 6e 20 6e 6f 72  x $line 2]\n nor
18c0: 6d 0a 20 20 20 20 2e 6d 73 67 2e 74 20 73 65 65  m.    .msg.t see
18d0: 20 65 6e 64 0a 20 20 20 20 62 65 6c 6c 0a 20 20   end.    bell.  
18e0: 20 20 77 6d 20 64 65 69 63 6f 6e 69 66 79 20 2e    wm deiconify .
18f0: 0a 20 20 20 20 75 70 64 61 74 65 0a 20 20 20 20  .    update.    
1900: 72 61 69 73 65 20 2e 0a 20 20 7d 20 65 6c 73 65  raise ..  } else
1910: 69 66 20 7b 24 63 6d 64 3d 3d 22 6e 6f 6f 70 22  if {$cmd=="noop"
1920: 7d 20 7b 0a 20 20 20 20 23 20 64 6f 20 6e 6f 74  } {.    # do not
1930: 68 69 6e 67 0a 20 20 7d 20 65 6c 73 65 69 66 20  hing.  } elseif 
1940: 7b 24 63 6d 64 3d 3d 22 6d 65 74 61 22 7d 20 7b  {$cmd=="meta"} {
1950: 0a 20 20 20 20 73 65 74 20 6e 6f 77 20 5b 63 6c  .    set now [cl
1960: 6f 63 6b 20 73 65 63 6f 6e 64 73 5d 0a 20 20 20  ock seconds].   
1970: 20 73 65 74 20 74 69 6d 65 20 5b 63 6c 6f 63 6b   set time [clock
1980: 20 66 6f 72 6d 61 74 20 24 6e 6f 77 20 2d 66 6f   format $now -fo
1990: 72 6d 61 74 20 7b 25 48 3a 25 4d 7d 20 2d 67 6d  rmat {%H:%M} -gm
19a0: 74 20 31 5d 0a 20 20 20 20 2e 6d 73 67 2e 74 20  t 1].    .msg.t 
19b0: 69 6e 73 65 72 74 20 65 6e 64 20 22 5c 5b 24 74  insert end "\[$t
19c0: 69 6d 65 5c 5d 20 5b 6c 69 6e 64 65 78 20 24 6c  ime\] [lindex $l
19d0: 69 6e 65 20 31 5d 5c 6e 22 20 6d 65 74 61 0a 20  ine 1]\n" meta. 
19e0: 20 20 20 2e 6d 73 67 2e 74 20 73 65 65 20 65 6e     .msg.t see en
19f0: 64 0a 20 20 7d 20 65 6c 73 65 69 66 20 7b 24 63  d.  } elseif {$c
1a00: 6d 64 3d 3d 22 66 69 6c 65 22 7d 20 7b 0a 20 20  md=="file"} {.  
1a10: 20 20 69 66 20 7b 5b 69 6e 66 6f 20 63 6f 6d 6d    if {[info comm
1a20: 61 6e 64 73 20 68 61 6e 64 6c 65 5f 66 69 6c 65  ands handle_file
1a30: 5d 3d 3d 22 68 61 6e 64 6c 65 5f 66 69 6c 65 22  ]=="handle_file"
1a40: 7d 20 7b 0a 20 20 20 20 20 20 68 61 6e 64 6c 65  } {.      handle
1a50: 5f 66 69 6c 65 20 5b 6c 69 6e 64 65 78 20 24 6c  _file [lindex $l
1a60: 69 6e 65 20 31 5d 20 5b 6c 69 6e 64 65 78 20 24  ine 1] [lindex $
1a70: 6c 69 6e 65 20 32 5d 20 5b 6c 69 6e 64 65 78 20  line 2] [lindex 
1a80: 24 6c 69 6e 65 20 33 5d 0a 20 20 20 20 7d 0a 20  $line 3].    }. 
1a90: 20 7d 0a 7d 20 20 20 20 0a 0a 23 20 48 61 6e 64   }.}    ..# Hand
1aa0: 6c 65 20 61 20 62 72 6f 6b 65 6e 20 73 6f 63 6b  le a broken sock
1ab0: 65 74 20 63 6f 6e 6e 65 63 74 69 6f 6e 0a 23 0a  et connection.#.
1ac0: 70 72 6f 63 20 64 69 73 63 6f 6e 6e 65 63 74 20  proc disconnect 
1ad0: 7b 7d 20 7b 0a 20 20 67 6c 6f 62 61 6c 20 53 4f  {} {.  global SO
1ae0: 43 4b 45 54 0a 20 20 63 6c 6f 73 65 20 24 53 4f  CKET.  close $SO
1af0: 43 4b 45 54 0a 20 20 73 65 74 20 71 20 5b 74 6b  CKET.  set q [tk
1b00: 5f 6d 65 73 73 61 67 65 42 6f 78 20 2d 69 63 6f  _messageBox -ico
1b10: 6e 20 65 72 72 6f 72 20 2d 74 79 70 65 20 79 65  n error -type ye
1b20: 73 6e 6f 20 2d 70 61 72 65 6e 74 20 2e 20 2d 6d  sno -parent . -m
1b30: 65 73 73 61 67 65 20 5c 0a 20 20 20 20 20 20 20  essage \.       
1b40: 20 20 20 20 22 54 43 50 2f 49 50 20 6c 69 6e 6b      "TCP/IP link
1b50: 20 6c 6f 73 74 2e 20 20 54 72 79 20 74 6f 20 72   lost.  Try to r
1b60: 65 63 6f 6e 6e 65 74 3f 22 5d 0a 20 20 69 66 20  econnet?"].  if 
1b70: 7b 24 71 3d 3d 22 79 65 73 22 7d 20 7b 0a 20 20  {$q=="yes"} {.  
1b80: 20 20 63 6f 6e 6e 65 63 74 0a 20 20 7d 20 65 6c    connect.  } el
1b90: 73 65 20 7b 0a 20 20 20 20 65 78 69 74 0a 20 20  se {.    exit.  
1ba0: 7d 0a 7d 0a 0a 23 20 52 65 6d 6f 76 65 20 61 6c  }.}..# Remove al
1bb0: 6c 20 62 75 74 20 74 68 65 20 6d 6f 73 74 20 72  l but the most r
1bc0: 65 63 65 6e 74 20 31 30 30 20 6d 65 73 73 61 67  ecent 100 messag
1bd0: 65 20 66 72 6f 6d 20 74 68 65 20 6d 65 73 73 61  e from the messa
1be0: 67 65 20 6c 6f 67 0a 23 0a 70 72 6f 63 20 63 6c  ge log.#.proc cl
1bf0: 65 61 6e 75 70 5f 72 65 63 6f 72 64 20 7b 7d 20  eanup_record {} 
1c00: 7b 0a 20 20 2e 6d 73 67 2e 74 20 64 65 6c 65 74  {.  .msg.t delet
1c10: 65 20 31 2e 30 20 7b 65 6e 64 20 2d 31 30 30 20  e 1.0 {end -100 
1c20: 6c 69 6e 65 73 7d 0a 7d 0a                       lines}.}.