home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / lispmachine / lmipro.lsp < prev    next >
Text File  |  2020-01-01  |  59KB  |  1,773 lines

  1. ;;; -*- Mode:LISP; Package:KERMIT; Ibase:8; Base:8; Readtable:T -*-
  2. ;1; Note that Ibase and Readtable are not known and are ignored on 3600.
  3.  
  4. ;******************************************************************************
  5. ; Copyright (c) 1984, 1985 by Lisp Machine Inc.
  6. ; Symbolics-specific portions Copyright (c) 1985 by Honeywell, Inc.
  7. ; Permission to copy all or part of this material is granted, provided
  8. ; that the copies are not made or distributed for resale, and the 
  9. ; copyright notices and reference to the source file and the software
  10. ; distribution version appear, and that notice is given that copying is
  11. ; by permission of Lisp Machine Inc.  LMI reserves for itself the 
  12. ; sole commercial right to use any part of this KERMIT/H19-Emulator
  13. ; not covered by any Columbia University copyright.  Inquiries concerning
  14. ; copyright should be directed to Mr. Damon Lawrence at (213) 642-1116.
  15. ;
  16. ; Version Information:
  17. ;      LMKERMIT 1.0     --      Original LMI code, plus edit ;1; for 3600 port
  18. ;
  19. ; Authorship Information:
  20. ;      Mark David (LMI)           Original version, using KERMIT.C as a guide
  21. ;      George Carrette (LMI)      Various enhancements
  22. ;      Mark Ahlstrom (Honeywell)  Port to 3600 (edits marked with ";1;" comments)
  23. ;
  24. ; Author Addresses:
  25. ;      George Carrette     ARPANET: GJC at MIT-MC
  26. ;
  27. ;      Mark Ahlstrom       ARPANET: Ahlstrom at HI-Multics
  28. ;                          PHONE:   (612) 887-4006
  29. ;                          USMAIL:  Honeywell MN09-1400
  30. ;                                   Computer Sciences Center
  31. ;                                   10701 Lyndale Avenue South
  32. ;                                   Bloomington, MN  55420
  33. ;******************************************************************************
  34.  
  35.  
  36. ;;; Pre-initial release changes to this module...
  37. ;;;   6/21/85  Slight modification to prevent divide by zero in give-state-info, MLA
  38.  
  39. ;;; KERMIT in LISP by Mark David at LMI
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46. ;;; this implementation is based on and closely resembles
  47. ;;; kermit for unix, written in c by columbia university.
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54. ;;; this file encodes the basic protocol for sending
  55. ;;; and receiving files to/from any other kermit.
  56. ;;; the two highest level functions, which are not
  57. ;;; however user functions, that are in this file are:
  58. ;;; SENDSW -- the send state table switcher and dispatcher
  59. ;;; RECSW -- the receive state table switcher and dispatcher
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67. ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  68. ;;; SOME POINTERS TO "KERMIT-" OTHER FILES:
  69. ;;;________________________________________
  70. ;;;
  71.  
  72.  
  73.  
  74. ;;; @@@ main: toplevel
  75. ;;;=
  76. ;;; main routine - parse command and options, set up the tty lines,
  77. ;;; and dispatch to the appropriate routine.
  78. ;;;=
  79. ;;; ;; (...
  80. ;;;      ;; (make-serial-stream ...)
  81. ;;;      ;;... )
  82. ;;;
  83. ;;;
  84. ;;; FOR THE MAIN TOPLEVEL INTERFACE ROUTINES SEE THE FILE:
  85. ;;;       "sys: kermit; window" and "sys: kermit; calls"
  86. ;;;
  87. ;;;  the window file runs the window interface to kermit. upon
  88. ;;;  selection of a routine on the command menu, a call is made
  89. ;;;  to a top level function defined in calls.  the calls
  90. ;;;  file contains the top level calls as methods of the flavor
  91. ;;;  kstate. a kstate instance has special instance variables
  92. ;;;  corresponding to most of the specials declared here.
  93. ;;;
  94. ;;;  there is a special variable called KSTATE bound to the current
  95. ;;;  instance of kstate. Thus (funcall 'kstate ':send-files) is the
  96. ;;;  form called when you mouse "Send" on the kermit command menu.
  97.  
  98.  
  99. ;;;  thus, you must change the instance variables of a kstate
  100. ;;;  flavor instance to affect the binding of the specials during
  101. ;;;  execution of its methods.
  102. ;;;
  103. ;;;  thus "reinitializing" is just evaluating the form
  104. ;;;       (setq kstate (make-instance 'kstate))
  105.  
  106.  
  107.  
  108. ;;;
  109.  
  110.  
  111.  
  112. ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  113. ;;; @@@ CONNECT
  114. ;;;
  115. ;;; connect with another kermit over an assigned tty line.
  116. ;;; some degree of terminal emulation is attempted.
  117. ;;;
  118. ;;; FOR THE Connect FUNCTION:
  119. ;;;
  120. ;;; SEE THE FILE:  "sys:kermit; terminal"
  121.  
  122.  
  123.  
  124. ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  125. ;;; @@@ SERVER (talk to one)
  126. ;;;
  127. ;;; Defined in calls, basically.
  128.  
  129.  
  130.  
  131.  
  132. ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  133. ;;; @@@ SERVER (be one)
  134. ;;;
  135. ;;; a login server interface is in "SYS: KERMIT; PS-TERMINAL"
  136. ;;; a KERMIT server is coded in "SYS: KERMIT; SERVER"
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144. ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  145. ;;; @@@ OPENNING FILE STUFF
  146. ;;;
  147. ;;; FOR THE OPENNING FILE STUFF, SEE THE FILE:
  148. ;;;
  149. ;;;       "sys:kermit;open.lisp"
  150. ;;;
  151. ;;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  152.  
  153.  
  154.  
  155. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  156.  
  157. ;basic KERMIT protocol:
  158.  
  159. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  160.  
  161.  
  162.  
  163. (DECLARE (SPECIAL INTERACTION-PANE DEBUG-PANE STATUS-PANE))
  164.  
  165.  
  166.  
  167.  
  168.  
  169. ;;; @@@ SYMBOL DEFINITIONS ["'constants'"]
  170.  
  171. ;;; actually should be initialized by making an instance of kstate (in the file
  172. ;;; calls) which calls the functions herein with these (mostly) as special
  173. ;;; instance variables.
  174.  
  175.  
  176.  
  177.  
  178. (DEFCONST *MAXPACKSIZ* #O136 "maximum packet size")
  179.  
  180.  
  181. (DEFCONST *SOH* 1 "start of header")
  182.  
  183.  
  184. (DEFCONST *CR* #O15 "ascii carriage return")
  185.  
  186.  
  187. (DEFCONST *DEL* #O177 "ascii delete (rubout)")
  188.  
  189.  
  190. (DEFCONST *ESCCHR* #\NETWORK "default escape char for Connect")
  191.  
  192.  
  193.  
  194. (DEFCONST *MAXTRY* #O12 "times to retry a packet")
  195.  
  196.  
  197.  
  198. (DEFCONST *MYQUOTE* #\# "Quote character I want to use to quote /"control characters/"")
  199.  
  200.  
  201.  
  202. (DEFCONST *MYPAD* 0 "number of padding characters I require")
  203.  
  204.  
  205.  
  206. (DEFCONST *MYPCHAR* 0 "char I will use as a padding char")
  207.  
  208.  
  209.  
  210. (DEFCONST *MYEOL* #O15 "my kind of return char")  ; LM's 215, which won't fit in 7 bits...?
  211.  
  212.  
  213.  
  214. (DEFCONST *MYTIME* #O12 "seconds after which i should be timed out")
  215.  
  216.  
  217.  
  218. (DEFCONST *MAXTIM* #O74 "maximum timeout interval in seconds")
  219.  
  220.  
  221.  
  222. (DEFCONST *MINTIM* 2 "minimum timeout interval in seconds")
  223.  
  224.  
  225.  
  226.  
  227. (DEFCONST *CHECKSUM-TYPE* 1 "1 for one character checksum, 2 for 2-character. 3 not available.")
  228.  
  229.  
  230.  
  231.  
  232. (DEFCONST *TRUE* -1 "-1 = boolean constant true")
  233.  
  234.  
  235.  
  236.  
  237. (DEFCONST *FALSE* 0 "0 = boolean constant false")
  238.  
  239.  
  240.  
  241.  
  242.  
  243. ;;; @@@global variables
  244.  
  245.  
  246. ;;; integers:
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253. (DEFVAR *RPSIZ*  0 "maximum receive packet size")
  254.  
  255.  
  256.  
  257. (DEFVAR *SPSIZ*  0 "maximum send packet size")
  258.  
  259.  
  260.  
  261. (DEFVAR *PAD* 0 "how much padding to send")
  262.  
  263.  
  264.  
  265. (DEFVAR *TIMINT* 0 "timeout for foreign host on sends")
  266.  
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273.  
  274. (DEFVAR *REMOTE* NIL "t means we're a remote kermit")
  275.  
  276.  
  277.  
  278. (DEFVAR *FILECOUNT* 0 "number of files left to send")
  279.  
  280.  
  281.  
  282.  
  283. (DEFVAR *SIZE* 0 "size of present data")
  284.  
  285.  
  286.  
  287.  
  288. (DEFVAR *PACKET-NUMBER* 0 "the packet number")
  289.  
  290.  
  291.  
  292. (DEFVAR *NUMTRY* 0 "times this packet retried")
  293.  
  294.  
  295.  
  296. (DEFVAR *OLDTRY* 0 "times previous packet retried")
  297.  
  298.  
  299.  
  300.  
  301.  
  302. ;;; @@@ CHARACTERS:
  303.  
  304. (DEFVAR *QUOTE* 0 "quote character in incoming data")
  305.  
  306.  
  307.  
  308. (DEFVAR *STATE* 0 "present state of the machine")
  309.  
  310.  
  311.  
  312. (DEFVAR *PADCHAR* 0  "padding character to send")
  313.  
  314.  
  315.  
  316. (DEFVAR *EOL* #O15 "end-of-line character to send")
  317.  
  318.  
  319.  
  320. (DEFVAR *ESCCHR* 0 "quote character in incoming data")
  321.  
  322.  
  323.  
  324. (DEFVAR *EOF* 0 "character marking end of file")
  325.  
  326.  
  327.  
  328. ;;; other data types:
  329.  
  330.  
  331. (DEFVAR BUFEMP-IGNORE-LINE-FEED NIL
  332.   "Initially nil for each file, this tells bufemp whether
  333.   to ignore the line feed or not at this point in the
  334.   file over an entire file transfer.")
  335.  
  336.  
  337.  
  338.  
  339.  
  340. (DEFVAR *FILNAMCNV* ':GENERIC
  341.   ":GENERIC means do filename conversions to generic standards.
  342.           ...others will be here some day...")
  343.  
  344.  
  345.  
  346.  
  347.  
  348. (DEFVAR DATA-XFER-START-TIME :UNBOUND "Start time of this xfer")
  349.  
  350. (DEFVAR *BYTECOUNT* :UNBOUND "Bytes sent during this xfer, roughly")
  351.  
  352. (DEFVAR *FILE-CLOSING-DISPOSITION* ':ABORT "How to handle partially finished files, delete
  353.         or just close?")
  354.  
  355.  
  356. (DEFVAR *SUCCESSFUL-TRANSACTIONS* ()
  357.   "a list of lists:(<true-pathname> <time> <:send or :receive>")
  358.  
  359.  
  360. (defvar current-file-props-list ()
  361.   "Holds a list of properties to put on the currently transfered file if non-nil")
  362. ;; especially useful, since no one has implemented attributes protocol yet.
  363.  
  364.  
  365.  
  366.  
  367. (defvar ascii-extra-safe-char)
  368.  
  369. (defvar ascii-extra-safe-filter?)
  370.  
  371.  
  372. (defvar *8-bit-lispm* t
  373.   ;; see bufill, bufemp for the affect of this flag
  374.   "Mode with fullest translation of lispm into//from ascii.
  375.  -formatting chars (like RETURN) are stripped of their 8th bit,
  376.  which makes them look like their corresponding ascii values.
  377.  -greek chars (like lambda) and #o177 are quoted by DEL (ascii #o177).")
  378.  
  379.  
  380.  
  381. (DEFVAR *IMAGE* NIL "t means 8-bit mode, no ascii//lispm translations")
  382.  
  383.  
  384.  
  385.  
  386.  
  387. (DEFVAR *DEBUG* NIL "t means supply debugging info as you run")
  388.  
  389.  
  390.  
  391.  
  392.  
  393. (DEFVAR *FILELIST* () "list of files to be sent")
  394.  
  395.  
  396. (DEFVAR *FILNAM* NIL "current file name")
  397.  
  398. (defvar *as-filnam* nil "If non-nil, a string naming a filename to receive/send AS")
  399.  
  400.  
  401. (defvar *string-array-buffer*
  402.           (make-array (* 2 *maxpacksiz*) ':type 'art-string    ;1; changed from :art-string to art-string,
  403.                         ':fill-pointer 0)                    ;1; which should still be ok for LAMBDA
  404.   "Used as buffer for outgoing packets by spack")
  405.  
  406.  
  407.  
  408.  
  409. (defvar *recpkt*
  410.           (make-array *maxpacksiz*
  411.                         ':type 'art-string    ;1; changed from :art-string to art-string,
  412.                         ':fill-pointer 0)    ;1; which should still be ok for LAMBDA
  413.   "receive packet buffer")
  414.  
  415.  
  416.  
  417.  
  418.  
  419. (defvar *packet*
  420.           (make-array *maxpacksiz*
  421.                         ':type 'art-string
  422.                         ':fill-pointer 0)
  423.   "packet buffer")
  424.  
  425.  
  426.  
  427.  
  428.  
  429. (defvar *ttyfd* nil "file descriptor of tty for i/o, 0 if remote")
  430.  
  431.  
  432.  
  433.  
  434. (defvar *fp*  nil "file pointer for current disk file")
  435.  
  436.  
  437.  
  438.  
  439. (defconst abort-transfer-flag nil "set true when current transfer is being aborted.")
  440.  
  441.  
  442. (defvar *kermit-beginning-time* nil "the universal time beginning of the current session.")
  443.  
  444. (defvar *packcount-wraparound* 0
  445.   "The number of times the packet count has /"wrapped
  446.           around/", i.e. went like ..., 98, 99, 0, 1,...). Updated by bump-packet-count.")
  447.  
  448.  
  449.  
  450. (defun update-status-label (filename sending?)
  451.   (and (boundp 'status-pane)
  452.        status-pane
  453.        (send status-pane ':set-cursorpos
  454.                0 (- (send status-pane ':line-height) 2)
  455.                ':character)
  456.        (format status-pane "~a ~a"
  457.                  (if sending? "Sending:" "Receiving:")
  458.                  (fs:parse-pathname filename))))
  459.  
  460.  
  461.  
  462. ;;; this draws state and packet info in the little
  463. ;;; status pane in the upper left hand corner of
  464. ;;; the kermit frame. only reports numtry, if its higher
  465. ;;; than zero.
  466.  
  467.  
  468. ;;; some day make this a method of the status pane.
  469. ;;; and let the status pane keep field info to only erase
  470. ;;; changed parts.
  471.  
  472.  
  473. (defvar bps 0. "bytes per second this transfer")
  474.  
  475. (defun give-state-info (state n ntries)
  476.  
  477.   (send status-pane ':home-cursor)
  478.   (send status-pane #-3600 ':clear-eol #+3600 ':clear-rest-of-line)    ;1; 
  479.  
  480.   (format status-pane ": ~14A  :  ~3D  :  ~D"
  481.             (selectq state
  482.               (#\D "Data")
  483.               (#\S "Send Init")
  484.               (#\R "Receive Init")
  485.               (#\F "File Header")
  486.               (#\A "Abort")
  487.               (#\Z "Eof")
  488.               (#\B "Eot")
  489.               (#\C "Complete")
  490.               (0 "Unknown")
  491.               (t "unknown"))
  492.             (+ (* #o100 *packcount-wraparound*) n)
  493.             ntries)
  494.  
  495.   (and *bytecount*                                ;if so, assume data-xfer-start-time is ok too.
  496.        (let ((old-bps bps))
  497.            (cond ((< (floor old-bps)
  498.                        (setq bps
  499.                                (// *bytecount*
  500.                    ;1; To avoid divide by zero errors, do this...
  501.                    (let ((ourtime    ;1;
  502.                        (// (time-difference (time) data-xfer-start-time)
  503.                            #.(float 60.))))    ;1; changed small-float to float ** fix with inc compile
  504.                      (if (zerop ourtime) 1 ourtime))))    ;1;
  505.                        (ceiling old-bps)))
  506.                  (t (terpri status-pane)
  507.                       (send status-pane #-3600 ':clear-eol #+3600 ':clear-rest-of-line)    ;1; 
  508.                       (format status-pane "~%Bytes Per Second: ~D" (fix bps))))))
  509.   )
  510.  
  511. ;;; @@@ MACRO DEFINITIONS
  512.  
  513.  
  514.  
  515.  
  516. ;;; @@@ WARN-USER
  517.  
  518. (defmacro warn-user (format-string . format-args)
  519.   `(cond (*debug*
  520.             (format interaction-pane "~% Warning: ")
  521.             (format interaction-pane ,format-string . ,format-args))))
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530. ;;; @@@ TOCHAR, UNCHAR, CTL
  531. ;;; Tochar: converts a control character to a printable one by adding a space.
  532. ;;;
  533. ;;; Unchar: undoes tochar.
  534. ;;;
  535. ;;; Ctl:    converts between control characters and printable characters by
  536. ;;;         toggling the control bit (i.e. ^a becomes a and a becomes ^a).
  537.  
  538.  
  539.  
  540. (DEFSUBST TOCHAR (CH)
  541.   (+ CH #\SPACE))
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548. (DEFSUBST UNCHAR (CH)
  549.   (- CH #\SPACE))
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556. (DEFSUBST CTL (CH)
  557.   (LOGXOR CH #o100))
  558.  
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566. ;;; Syncf decrements the value of num
  567. ;;; by 1 or sets it back to 77 when it reaches
  568. ;;; 0.
  569.  
  570. (DEFMACRO SYNCF (NUM)
  571.   `(SETQ ,NUM (IF (< (DECF ,NUM) 0) 77 ,NUM)))
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579. ;;; Bump-packet-number adds one to *PACKET-NUMBER* modulo 100
  580. ;;; (octal). *packet-number* is the global packet count, which
  581. ;;; must be agreed upon by the two interacting KERMITs.
  582.  
  583. ;;; *packet-wraparound* is maintained for the sake of
  584. ;;; statistics hacks, so total packet count can be kept.
  585.  
  586. (defsubst bump-packet-number ()
  587.   (cond ((not (< (setq *packet-number* (1+ *packet-number*)) #o100))
  588.            (incf *packcount-wraparound*)
  589.            (setq *packet-number* 0))))
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597. (defsubst compute-final-checksum (chksum)
  598.   (logand (+ (ash (logand chksum #o0300) -6) chksum) #o077))
  599.  
  600.  
  601.  
  602.  
  603.  
  604. ;;;; 2-char-checksum
  605. ;;; This will be in the code soon as an optional feature.
  606. ;;; Its not considered necessary or advisable to use this,
  607. ;;; but that's up to the user. Here's what: we allocate one
  608. ;;; cons. Its car is the fixnum representing the 1st char
  609. ;;; and its cdr is the fixnum representing the 2nd char.
  610. ;;; This check sum is based on the low order 12 bits of the
  611. ;;; checksum. The first character is bits 6-11, and the second
  612. ;;; character is bits 0-5.
  613.  
  614.  
  615.  
  616. (DEFCONST 2-CHAR-CHECKSUM-CONS '(0 . 0) "The cons whose car and cdr hold a 2 char cksum")
  617.  
  618. (DEFUN COMPUTE-2-CHAR-CHECKSUM (CHECKSUM)
  619.   (SETF (CAR 2-CHAR-CHECKSUM-CONS) (LSH (LOGAND CHECKSUM 7700) -6))
  620.   (SETF (CDR 2-CHAR-CHECKSUM-CONS) (LOGAND CHECKSUM 77))
  621.   2-CHAR-CHECKSUM-CONS)
  622.  
  623.  
  624.  
  625.  
  626.  
  627. ;;; @@@ ACKP, NACKP, ERRP, FAILP
  628.  
  629. ;;; predicate macros applied to the type of response from rpack:
  630. ;;; an ACK (Y), a NACK (N), an ERRORMESSAGE (E), or a failed
  631. ;;; packet transmission (type = *FALSE*).
  632.  
  633. ;;; we use eq instead of = because its supposed to be
  634. ;;; faster on lisp machines (for fixnums).
  635.  
  636.  
  637. (DEFMACRO ACKP (TYPE)
  638.   `(EQ ,TYPE #\Y))
  639.  
  640.  
  641.  
  642.  
  643.  
  644. (DEFMACRO NACKP (TYPE)
  645.   `(EQ ,TYPE #\N))
  646.  
  647.  
  648.  
  649.  
  650.  
  651. (DEFMACRO ERRP (TYPE)
  652.   `(EQ ,TYPE #\E))
  653.  
  654.  
  655.  
  656.  
  657.  
  658. (DEFMACRO FAILP (TYPE)
  659.   `(EQ ,TYPE 0))                                  ;0 = BOOLEAN FALSE
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667. \014
  668.  
  669. ;;; CONCERNING SENDING LISPM FILES TO ASCII COMPUTERS:
  670.  
  671. ;;; from the greenual:
  672. ;;; "...In the currently implemented ASCII file servers, the following encoding is used.
  673. ;;; All printing characters and any characters not mentioned explicitly
  674. ;;; here are represented as themselves. Codes 010 (lambda), 011 (gamma)
  675. ;;; 012 (delta), 014 (plus-minus), 015 (circle-plus), 177 (integral),
  676. ;;; 200 through 207 inclusinve, 213 (delete), and 216 and anything
  677. ;;; higher are preceeded by a 177; that is, 177 is used as a "quoting
  678. ;;; character" for these codes. Codes 210 (overstrike) 211 (tab), 212
  679. ;;; (line), and 214 (page), are converted to their ascii cognates,
  680. ;;; namely 010 (backspace), 011 (horizontal tab), 012 (line feed), and
  681. ;;; 0145 (form feed) respectively. code 215 (return) is converted into
  682. ;;; 015 (carriage return) followed by 012 (line feed).
  683. ;;; Code 377 is ignored completely, and so cannot be stored in files."
  684.  
  685. ;;; *** someday, think about using this, but note that, e.g. 11 [ ] would
  686. ;;; expand into ## , a quadruple expansion! That's because 177 [] is
  687. ;;; ascii rubout, which must be control quoted by kermit.
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696.  
  697. (COMMENT
  698. (DEFUN ASCII-TO-LISPM (CH)
  699.   ;; note! it is not presently the case that CH = (LISPM-TO-ASCII (ASCII-TO-LISPM CH)) FOR
  700.   ;; ANY CH. Not too good. This is not actually used right now.!!!
  701.   "Converts ascii to lispm as well as possible, which sometimes
  702.           means returning >8bit numbers, in which case we usually punt with ()."
  703.   (IF (EQ CH 177)
  704.       #\RUBOUT
  705.     (IF (MEMQ CH '(#O10 #O11 #O12 #O14 #O15))
  706.           (+ CH #O200)
  707.       (IF (< CH #\SPACE)
  708.             NIL
  709.           CH))))
  710. )
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718. (COMMENT
  719. (DEFUN LISPM-TO-ASCII (CH)
  720.   "May return nil in case of high bit numbers; also, in case of
  721.           greek characters { ,  ,  ,  ,  } [10, 11, 12, 14, and 15
  722.           octal], it will return nil, since these are the translations
  723.           for PAGE, TAB, RETURN, OVERSTRIKE, and LINEFEED, and so would
  724.           cause conflict. This may change but we have to devise a better
  725.           lispm-ascii translation convention than in greenual, p. 134"
  726.   (SELECTQ CH
  727.     (#\RUBOUT #O177)
  728.     ((#\PAGE #\TAB #\RETURN #\OVERSTRIKE #\LINEFEED) (- CH #O200))
  729.     ((#O10 #O11 #O12 #O14 #O15) NIL)
  730.     (:OTHERWISE (COND ((> CH #O177) NIL)
  731.                           (T CH)))))
  732. )
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740. ;;; @@@  BUFEMP
  741.  
  742. (defun bufemp (buffer len)
  743.   "Put data from an incoming packet into a local disk file."
  744.   (let ((temp-outbuf *string-array-buffer*))
  745.     (loop initially (setf (fill-pointer temp-outbuf) 0)
  746.             with i fixnum
  747.             until (>= i len)
  748.             as ch fixnum = (aref buffer i)
  749.  
  750.             doing
  751.  
  752.             (cond ((eq ch *myquote*)
  753.                      (setq ch (aref buffer (setq i (1+ i))))
  754.                      (unless (eq  (logand ch 177) *myquote*)
  755.                        (setq ch (ctl ch)))))
  756.             (cond (*image*
  757.                      (array-push temp-outbuf ch))
  758.                     (*8-bit-lispm*
  759.                        (cond ((eq ch #o177)                 ;lispm quoted
  760.                                 (setq ch (aref buffer (setq i (+ 2 i))))
  761.                                 (unless (eq ch #o177) (setq ch (ctl ch))))      ;get one after
  762.                                ((memq ch '(#o10 #o11 #o14))
  763.                                 (setq ch (+ ch 200)))
  764.                                ((eq ch #o12) (setq ch (cond (bufemp-ignore-line-feed
  765.                                                                    (setq bufemp-ignore-line-feed nil))
  766.                                                                   (t #\return))))
  767.                                ((eq ch #o15) (setq bufemp-ignore-line-feed t ch #\return)))
  768.                        (and ch (array-push temp-outbuf ch)))
  769.  
  770.                     (t (cond ((setq ch (selectq (setq ch (logand ch 177))
  771.                                              (#o10 #\overstrike)
  772.                                              (#o11 #\tab)
  773.                                              (#o12 (cond (bufemp-ignore-line-feed
  774.                                                               (setq bufemp-ignore-line-feed nil))
  775.                                                              (t #\return)))
  776.                                              (#o14 #\page)
  777.                                              (#o15 (setq bufemp-ignore-line-feed t)
  778.                                                      #\return)
  779.                                              #+3600 (#o177 #\rubout)    ;1; delete not in
  780.                          #-3600 (#o177 #\delete)    ;1; 3600 Rel 6
  781.                                              (:otherwise ch)))
  782.                                 (array-push temp-outbuf ch)))))
  783.             (incf i)
  784.             finally (send *fp* ':string-out temp-outbuf)))
  785.   buffer)
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.  
  798.  
  799.  
  800.  
  801.  
  802. ;;; @@@ bufill
  803.  
  804. ;;;; bufill (buffer)
  805. ;;; There are four ways to fill a buffer:
  806. ;;; 1. kermit default: 7-bit, quote all control characters, map newlines
  807. ;;; and tabs and any other funny characters into ascii.
  808. ;;;
  809. ;;; 2. lisp machine default: (*8-bit-lispm*)
  810. ;;;   as described in Chineual and honoring kermit as well by quoting
  811. ;;;   control characters.
  812. ;;; 3. *image*
  813. ;;;   send everything thru with no conversion, except for quoting the
  814. ;;;   quote character.
  815. ;;; 4. ascii-extra-safe-filter?
  816. ;;;   like 1. but filter out any characters less than #\space
  817. ;;;   which are commonly used on lisp machines (such as greek characters
  818. ;;;   and less-than-or-equal-sign.) The value should be a filtering
  819. ;;;   function that looks for wierd characters. [Note: it should not
  820. ;;;   need filter out formatting chars like RETURN and TAB. These
  821. ;;;   are already handled.
  822. ;;;
  823. ;;; Right now these may interfere in wierd ways. Fix this up alot.
  824. ;;; To do: repeat count prefixing!
  825. ;;;  optional huffman encoding?
  826.  
  827.  
  828. ;1; Commented this out, since it seems to be superseded by the next definition.
  829. ;(defun bufill (buffer)
  830. ;  "fill buffer with the outgoing data from the file *FP* points to.
  831. ;   only control quoting is done; 8-bit and
  832. ;    repeat count prefixes are not handled."
  833. ;  (let ((fullsize (- *spsiz* 6)))
  834. ;    (loop initially (setf (fill-pointer buffer) 0)
  835. ;            until  (>= (fill-pointer buffer) fullsize)
  836. ;            for c fixnum = (send *fp* ':tyi nil)
  837. ;            when (null c) do (loop-finish)
  838. ;
  839. ;            doing
  840. ;            (cond ((not (and (>= c #\sp) (< c #o177)))
  841. ;                     (cond (ascii-extra-safe-filter?
  842. ;                              (setq c
  843. ;                                    (funcall ascii-extra-safe-filter? c))))))
  844. ;            (cond ((and (>= c #\sp) (< c #o177)
  845. ;                          (not (eq c *quote*)))   ;regular character
  846. ;                     (array-push buffer c))
  847. ;                    ((eq c *quote*)                         ;control quote character
  848. ;                     (array-push buffer *quote*)
  849. ;                     (array-push buffer *quote*))
  850. ;                    ((not *image*)                          ;do lispm -> ascii mapping if not image mode.
  851. ;                     (cond ((eq c 215)                      ;carriage return
  852. ;                              (array-push buffer *quote*)
  853. ;                              (array-push buffer (ctl #o12))
  854. ;                              (array-push buffer *quote*)
  855. ;                              (array-push buffer (ctl #o15)))
  856. ;                           ((memq c '(#\overstrike #\tab #\line #\page))        ;lispm control characters
  857. ;                              (setq c (logand c #o177))
  858. ;                              (array-push buffer *quote*)
  859. ;                              (array-push buffer (ctl c)))
  860. ;                           ((and *8-bit-lispm*
  861. ;                                   (or (memq c '(#+3600 #\rubout #-3600 #\delete #o177))    ;1; 
  862. ;                                         (> c #o177)))
  863. ;                              (array-push buffer *quote*)
  864. ;                              (array-push buffer #o177)
  865. ;                              (if (eq c #o177) (array-push buffer *quote*))
  866. ;                              (array-push buffer c))
  867. ;                           ((or (memq c '(#o10 #o11 #o12 #o14 #o15))
  868. ;                                  (>= c 177))               ;losing lispm characters
  869. ;                              (cond (*8-bit-lispm*
  870. ;                                     (cond ((< c #o177)
  871. ;                                              (array-push buffer *quote*)
  872. ;                                              (array-push buffer #o177)
  873. ;                                              (array-push buffer *quote*)
  874. ;                                              (array-push buffer (ctl c)))
  875. ;                                             (t (array-push buffer *quote*)
  876. ;                                                  (array-push buffer #o177)
  877. ;                                                  (array-push buffer c))))
  878. ;
  879. ;                                    (t (warn-user ;wierd char don't send anything for it.
  880. ;                                           "~&The character ~C [~O octal] could not~A"
  881. ;                                           c c " be translated to ASCII."))))
  882. ;                           (t (array-push buffer *quote*)   ;normal case to *quote*
  883. ;                                (array-push buffer c))))
  884. ;                    (t (array-push buffer *quote*)
  885. ;                       (array-push buffer c)))
  886. ;            finally
  887. ;            (return (cond ((zerop (fill-pointer buffer))
  888. ;                               *eof*)
  889. ;                              (t (fill-pointer buffer)))))))
  890.  
  891. (defun bufill (buffer)
  892.   "fill buffer with the outgoing data from the file *FP* points to.
  893.    only control quoting is done; 8-bit and
  894.     repeat count prefixes are not handled."
  895.   (let ((fullsize (- *spsiz* 7)))        ;1; Changed 6 to 7!! See lmbugs.doc file item #14.
  896.     (loop with index = 0
  897.             until  (>= index fullsize)
  898.             for c fixnum = (send *fp* ':tyi nil)
  899.             doing
  900.             (cond ((null c) (loop-finish)))
  901.             (cond ((not (and (>= c #\sp) (< c #o177)))
  902.                      (cond (ascii-extra-safe-filter?
  903.                               (setq c (funcall ascii-extra-safe-filter? c))))))
  904.             (cond ((and (>= c #\sp) (< c #o177)
  905.                           (not (eq c *quote*)))   ;regular character
  906.                      (setf (aref buffer index) c)
  907.                      (incf index))
  908.                     ((eq c *quote*)                         ;control quote character
  909.                      (setf (aref buffer index) *quote*)
  910.                      (incf index)
  911.                      (setf (aref buffer index) *quote*)
  912.                      (incf index))
  913.                     ((not *image*)                          ;do lispm -> ascii mapping if not image mode.
  914.                      (cond ((eq c 215)                      ;carriage return
  915. ;1; Incompatible change here!!!
  916. ;1; Switched this around so it sends crlf rather than lfcf.
  917.                               (setf (aref buffer index) *quote*)
  918.                               (incf index)
  919.                               (setf (aref buffer index) (ctl #o15))
  920.                               (incf index)
  921.                               (setf (aref buffer index) *quote*)
  922.                               (incf index)
  923.                               (setf (aref buffer index) (ctl #o12))
  924.                               (incf index))
  925.                            ((memq c '(#\overstrike #\tab #\line #\page))        ;lispm control characters
  926.                               (setq c (logand c #o177))
  927.                               (setf (aref buffer index) *quote*)
  928.                               (incf index)
  929.                               (setf (aref buffer index) (ctl c))
  930.                               (incf index))
  931.                            ((and *8-bit-lispm* (>= c #o177))
  932.                               (setf (aref buffer index) *quote*)
  933.                               (incf index)
  934.                               (setf (aref buffer index) #o177)
  935.                               (incf index)
  936.                               (cond ((eq c #o177)
  937.                                      (setf (aref buffer index) *quote*)
  938.                                      (incf index)))
  939.                               (setf (aref buffer index) c)
  940.                               (incf index))
  941.                            ((or (memq c '(#o10 #o11 #o12 #o14 #o15))
  942.                                   (>= c 177))               ;losing lispm characters
  943.                               (cond (*8-bit-lispm*
  944.                                      (cond ((< c #o177)
  945.                                               (setf (aref buffer index) *quote*)
  946.                                               (incf index)
  947.                                               (setf (aref buffer index) #o177)
  948.                                               (incf index)
  949.                                               (setf (aref buffer index) *quote*)
  950.                                               (incf index)
  951.                                               (setf (aref buffer index) (ctl c))
  952.                                               (incf index))
  953.                                              (t (setf (aref buffer index) *quote*)
  954.                                                   (incf index)
  955.                                                   (setf (aref buffer index) #o177)
  956.                                                   (incf index)
  957.                                                   (setf (aref buffer index) c)
  958.                                                   (incf index))))
  959.  
  960.                                     (t (warn-user ;wierd char don't send anything for it.
  961.                                            "~&The character ~C [~O octal] could not~A"
  962.                                            c c " be translated to ASCII."))))
  963.                            (t (setf (aref buffer index) *quote*)      ;normal case to *quote*
  964.                                 (incf index)
  965.                                 (setf (aref buffer index) c)
  966.                                 (incf index))))
  967.                     (t (setf (aref buffer index) *quote*)
  968.                        (incf index)
  969.                        (setf (aref buffer index) c)
  970.                        (incf index)))
  971.  
  972.             finally
  973.             (return (cond ((zerop index)
  974.                                *eof*)
  975.                               (t index))))))
  976.  
  977.  
  978.  
  979.  
  980. (defselect (debugger-tell-user ignore)
  981.   (:gnxtfl (filelist)
  982.     (format debug-pane " ~&gnxtfl     next file is: ~A.~% k: ~D files remain"
  983.               (car filelist) (1- (length filelist))))
  984.   (:sendsw ()
  985.     (terpri debug-pane) (terpri debug-pane)
  986.     (format debug-pane "sendsw     state:    ~C      ~% " *state*))
  987.   (:recsw  ()
  988.     (terpri debug-pane) (terpri debug-pane)
  989.     (format debug-pane "recsw      state:    ~C      ~% " *state*))
  990.   (:rpack  (type num len data) data
  991.     (format debug-pane "~&rpack     TYPE>>~3C    NUM>>~3D    LEN>>~3D"
  992.               type num len))
  993.   (:spack  (type num len data) data
  994.     (format debug-pane "~&spack     TYPE>>~3C    NUM>>~3D    LEN>>~3D"
  995.               type num len
  996.               ))
  997.   (:spack-line (string)
  998.     (format debug-pane "~&send-packet>> ~S" string)))
  999.  
  1000.  
  1001. ;;; @@@ PRERRPKT
  1002. ;;;  Print error packet to the local user that came from the remote
  1003. ;;; KERMIT in an E packet.
  1004.  
  1005. (DEFUN PRERRPKT (MSG)
  1006.   "print contents of error packet received from remote host."
  1007.   (FORMAT INTERACTION-PANE
  1008.             "~&KERMIT aborting with following error from remote host:~%   ~S~%"
  1009.             MSG))
  1010.  
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029. (DEFUN FLUSHINPUT ()
  1030.   (SEND *TTYFD* ':CLEAR-INPUT))
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036. (DEFUN ERROR-MESSAGE (FORMAT-STRING &REST FORMAT-ARGS)
  1037.   ;;; THIS WILL DO FOR NOW...
  1038.   (APPLY #'FORMAT `(,INTERACTION-PANE ,FORMAT-STRING . ,FORMAT-ARGS)))
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051. ;;; toplevel sender/receiver:
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063. ;;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  1064.  
  1065. ;;;; @@@ SENDSW
  1066. ;;;
  1067. ;;;
  1068. ;;; This is the state table switcher for sending files to
  1069. ;;; a another KERMIT.
  1070.  
  1071. ;;; now checks out terminal-io steam for ABORT character:
  1072. ;; the abort character is CONTROL-Z.
  1073.  
  1074.  
  1075.  
  1076. (DEFUN SENDSW (&OPTIONAL (*STATE* #\S) (*PACKET-NUMBER* 0) (*NUMTRY* 0))
  1077.   ;; calls: sinit, sfile, sdata, seof, sbreak
  1078.   "sendsw is the state table switcher for sending files. it loops until
  1079.    either it finishes, or an error is encountered. the routines called
  1080.    by sendsw are responsible for changing the state."
  1081.   (UNWIND-PROTECT
  1082.       (LET (;(*STATE* #\S)                        ;INIT STATE,PACKET-NUMBER,NUMTRY
  1083.               ;(*PACKET-NUMBER* 0)
  1084.               ;(*NUMTRY* 0)
  1085.               (*PACKCOUNT-WRAPAROUND* 0)
  1086.               (ABORT-TRANSFER-FLAG NIL)
  1087.               (*bytecount* (if (eq *state* #\S) nil 0))
  1088.               (bps 0.))
  1089.           (LOOP                                             ; DO AS LONG AS NECESSARY
  1090.             WHEN *DEBUG* DO
  1091.             (DEBUGGER-TELL-USER ':SENDSW)
  1092.             DO
  1093.             (OR *REMOTE* (GIVE-STATE-INFO *STATE* *PACKET-NUMBER* *NUMTRY*))
  1094.             (COND ((EQ (SEND TERMINAL-IO ':TYI-NO-HANG) #\CONTROL-Z)
  1095.                      (COND ((MEMQ *STATE* '(#\D #\F #\Z))
  1096.                               (SETQ *STATE* #\Z ABORT-TRANSFER-FLAG T))
  1097.                            (T (SETQ *STATE* #\A)))
  1098.                      (FORMAT INTERACTION-PANE "...~C~%Aborting file transfer!" #\CONTROL-Z)))
  1099.             (SELECTQ *STATE*
  1100.               (#\S (SETQ *STATE* (SINIT)))        ; S SEND INIT
  1101.               (#\F (SETQ *STATE* (SFILE)))        ; F SEND FILE HEADER
  1102.               (#\D (SETQ *STATE* (SDATA)))        ; D SEND DATA
  1103.               (#\Z (SETQ *STATE* (SEOF)))                   ; Z SEND EOF - CTRL Z
  1104.               (#\B (SETQ *STATE* (SBREAK)))       ; B SEND BREAK (EOT)
  1105.               (#\C (RETURN *TRUE*))               ; C DONE COMPLETE
  1106.               (#\A (RETURN *FALSE*))              ; A DONE ABORT
  1107.               (:OTHERWISE (RETURN *FALSE*)))))    ; T DONE FAIL
  1108.     (COND (*FP* (SEND *FP* ':CLOSE)
  1109.                     (SETQ *FP* NIL)))             ;MAKE SURE NO FILES ARE HANGING OPEN
  1110.     ))
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127. ;;; @@@ SINIT
  1128. ;;;
  1129. ;;; the fields of send initiate:
  1130. ;;; 0. maxl 1. time 2. npad 3. padc 4. eol
  1131. ;;; 5. qctl 6. qbin 7. chkt 8. rept 9. capas ...
  1132. ;;;
  1133. ;;; but we only concern ourselves with eol and quote
  1134. ;;; at this point
  1135.  
  1136.  
  1137.  
  1138. (DEFUN SINIT ()
  1139.   "send initiate: send this host's parameters and get other side's back."
  1140.   (COND ((> *NUMTRY* *MAXTRY*) #\A)
  1141.           (T (INCF *NUMTRY*)
  1142.              (SETQ *PACKET* (SPAR *PACKET*))
  1143.              (FLUSHINPUT)
  1144.              (SPACK #\S *PACKET-NUMBER* 6 *PACKET*)
  1145.              (MULTIPLE-VALUE-BIND (REPLY NUM IGNORE RECPKT) (RPACK)
  1146.                (COND ((NACKP REPLY) *STATE*)
  1147.                        ((ACKP REPLY)
  1148.                         (COND ((NOT (= *PACKET-NUMBER* NUM))
  1149.                                  *STATE*)
  1150.                                 (T (SETQ *EOL* 0 *QUOTE* 0) ;INITIALIZE QUESTIONABLE PARAMS.
  1151.                                    (RPAR RECPKT)        ;CHECK AND SET DEFAULTS
  1152.                                    (AND (ZEROP *EOL*) (SETQ *EOL* *MYEOL*))
  1153.                                    (AND (ZEROP *QUOTE*) (SETQ *QUOTE* *MYQUOTE*))
  1154.                                    (SETQ *NUMTRY* 0)
  1155.                                    (BUMP-PACKET-NUMBER)
  1156.                                    #\F)))
  1157.                        ((ERRP REPLY) (PRERRPKT RECPKT) #\A)
  1158.                        ((FAILP REPLY) *STATE*)
  1159.                        (T #\A))))))
  1160.  
  1161.  
  1162. (DEFUN SFILE ()
  1163.   "open file, then send file header to other kermit, see if its accepted.
  1164. Then get first buffer full of data from the file if its ok to send."
  1165.   (PROG (NEW-FILE-NAME NEWLENGTH)
  1166.  
  1167.     (COND ((> *NUMTRY* *MAXTRY*) (RETURN #/A))
  1168.             (T (INCF *NUMTRY*)
  1169.                                                             ;this will try to send an error message
  1170.                                                             ;packet if trouble openning now.  -mhd
  1171.                (UNLESS *FP*
  1172.                  (AND *DEBUG* (DEBUGGER-TELL-USER ':SFILE *FILNAM*))
  1173.                  (COND ((NOT (SETQ *FP* (OPEN-FILE-IN-OR-NOT *FILNAM*)))
  1174.                           (SPACK #\E *PACKET-NUMBER* 45
  1175.                                    "kermit-q: Error in sending file header")
  1176.                           (ERROR-MESSAGE "~&Cannot open file ~A ~%" *FILNAM*)
  1177.                           (RETURN *FALSE*))))
  1178.  
  1179.                                                             ;ok, got a file open; let's rip!
  1180.                                                             ;first do file name conversions
  1181.  
  1182.                (SETQ NEW-FILE-NAME (or (prog1 *as-filnam*
  1183.                                                       (setq *as-filnam* nil))
  1184.                                              (STRING-FOR-KERMIT *FILNAM*)))
  1185.                (SETQ NEWLENGTH (STRING-LENGTH NEW-FILE-NAME))
  1186.                (FORMAT INTERACTION-PANE "~& K: Sending ~A as ~A" *FILNAM* NEW-FILE-NAME)
  1187.                (OR *REMOTE* (UPDATE-STATUS-LABEL *FILNAM* T))
  1188.  
  1189.                                                             ;now send file header to other kermit
  1190.  
  1191.                (SPACK #\F *PACKET-NUMBER* NEWLENGTH NEW-FILE-NAME)
  1192.  
  1193.                                                             ;what was the reply?
  1194.  
  1195.                (RETURN (MULTIPLE-VALUE-BIND (REPLY NUM IGNORE RECPKT) (RPACK)
  1196.                            (COND
  1197.                                ((NACKP REPLY)
  1198.                                 (SETQ NUM (IF (< (DECF NUM) 0) 63 NUM))
  1199.                                 (COND ((NOT (= NUM *PACKET-NUMBER*))
  1200.                                          *STATE*)
  1201.                                         (T #\A)))
  1202.  
  1203.                                ((ACKP REPLY)
  1204.                                 (COND ((NOT (= NUM *PACKET-NUMBER*)) *STATE*)
  1205.                                         (T (SETQ *NUMTRY* 0)
  1206.                                            (BUMP-PACKET-NUMBER)
  1207.                                            (SETQ DATA-XFER-START-TIME (TIME))   ;for status check/display
  1208.                                            (SETQ *SIZE* (BUFILL *PACKET*))
  1209.                                            (SETQ *BYTECOUNT* *SIZE*)  ;for status check/display info
  1210.                                            #\D)))
  1211.  
  1212.                                ((ERRP REPLY) (PRERRPKT RECPKT) #\A)
  1213.  
  1214.                                ((FAILP REPLY) *STATE*)
  1215.  
  1216.                                (T #\A))))))))
  1217.  
  1218.  
  1219.  
  1220. ;;; @@@ sdata
  1221.  
  1222.  
  1223. (DEFUN SDATA ()
  1224.   "send file data."
  1225.   (COND ((> *NUMTRY* *MAXTRY*) #\A)
  1226.           (T (INCF *NUMTRY*)
  1227.              (SPACK #\D *PACKET-NUMBER* *SIZE* *PACKET*)
  1228.              (MULTIPLE-VALUE-BIND (REPLY NUM IGNORE RECPKT) (RPACK)
  1229.                (COND ((NACKP REPLY)
  1230.                         (SYNCF NUM)
  1231.                         (COND ((NOT (= NUM *PACKET-NUMBER*)) *STATE*)
  1232.                                 (T #\A)))
  1233.                        ((ACKP REPLY)
  1234.                         (COND ((NOT (= *PACKET-NUMBER* NUM)) *STATE*)
  1235.                                 (T (SETQ *NUMTRY* 0)
  1236.                                    (BUMP-PACKET-NUMBER)
  1237.                                    (IF (= (SETQ *SIZE* (BUFILL *PACKET*)) *EOF*)
  1238.                                          #\Z
  1239.                                      (PROG1 #\D (SETQ *BYTECOUNT* (+ *BYTECOUNT* *SIZE*)))))))
  1240.                        ((ERRP REPLY) (PRERRPKT RECPKT) #\A)
  1241.                        ((FAILP REPLY) *STATE*)
  1242.                        (T #\A))))))
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249. ;;; @@@ SEOF
  1250.  
  1251. (DEFUN SEOF ()
  1252.   "send end-of-file"
  1253.   (COND ((> *NUMTRY* *MAXTRY*) #\A)
  1254.           (T (INCF *NUMTRY*)
  1255.              (COND (ABORT-TRANSFER-FLAG
  1256.                       (SPACK #\Z *PACKET-NUMBER* 1 "D"))    ;send a Discard if abortp
  1257.                      (T (SPACK #\Z *PACKET-NUMBER* 0 NIL)))
  1258.              (MULTIPLE-VALUE-BIND (REPLY NUM IGNORE DATA) (RPACK)
  1259.                (COND ((NACKP REPLY)
  1260.                         (SYNCF NUM)
  1261.                         (COND ((NOT (= NUM *PACKET-NUMBER*)) *STATE*)
  1262.                                 (T #\A)))
  1263.                        ((ACKP REPLY)
  1264.                         (COND ((NOT (= NUM *PACKET-NUMBER*))
  1265.                                  *STATE*)
  1266.                                 (T (SETQ *NUMTRY* 0)
  1267.                                    (BUMP-PACKET-NUMBER)
  1268.                                    (FORMAT INTERACTION-PANE
  1269.                                              "~%File sent successfully: ~A~%"
  1270.                                              (SEND *FP* ':TRUENAME))
  1271.                                    (PUSH (LIST (SEND *FP* ':TRUENAME) (TIME) ':SEND)
  1272.                                            *SUCCESSFUL-TRANSACTIONS*)
  1273.                                    (AND *DEBUG* (DEBUGGER-TELL-USER ':SEOF-CLOSE *FILNAM*))         ;
  1274.                                    (SEND *FP* ':CLOSE)
  1275.                                    (SETQ *FP* NIL)
  1276.                                    (AND *DEBUG* (DEBUGGER-TELL-USER ':SEOF-LOOKING))
  1277.                                    (COND ((NOT (GNXTFL)) #\B)
  1278.                                            (T (AND *DEBUG* (DEBUGGER-TELL-USER ':SEOF-FOUND *FILNAM*))
  1279.                                               #\F)))))
  1280.                        ((ERRP REPLY) (PRERRPKT DATA) #\A)
  1281.                        ((FAILP REPLY) *STATE*)
  1282.                        (T #\A))))))
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289.  
  1290. ;;; @@@ SBREAK
  1291.  
  1292. (DEFUN SBREAK ()
  1293.   "send break (eot)."
  1294.   (COND ((> *NUMTRY* *MAXTRY*) #\A)
  1295.           (T (INCF *NUMTRY*)
  1296.              (SPACK #\B *PACKET-NUMBER* 0 NIL)
  1297.              (MULTIPLE-VALUE-BIND (REPLY NUM IGNORE RECPKT) (RPACK)
  1298.                (COND ((NACKP REPLY)
  1299.                         (SYNCF NUM)
  1300.                         (COND ((NOT (= *PACKET-NUMBER* NUM))
  1301.                                  *STATE*)
  1302.                                 (T #\A)))
  1303.                        ((ACKP REPLY)
  1304.                         (COND ((NOT (= *PACKET-NUMBER* NUM))
  1305.                                  *STATE*)
  1306.                                 (T (SETQ *NUMTRY* 0)
  1307.                                    (BUMP-PACKET-NUMBER)
  1308.                                    #\C)))
  1309.                        ((ERRP REPLY) (PRERRPKT RECPKT) #\A)
  1310.                        ((FAILP REPLY) *STATE*)
  1311.                        (T #\A))))))
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323. ;;; @@@ RECSW
  1324. ;;;
  1325. ;;; This is the state table switcher and main dispatcher for
  1326. ;;; receiving a file from another KERMIT.
  1327.  
  1328. ;;; add abort key: CONTROL-Z
  1329.  
  1330. (DEFUN RECSW (&OPTIONAL (*STATE* #\R)(*PACKET-NUMBER* 0)(*NUMTRY* 0))
  1331.   ;;; use these functions: rinit, rfile, rdata.
  1332.   "this is the state table switcher for receiving files."
  1333.   (UNWIND-PROTECT
  1334.       (LET (;(*STATE* #\R)                        ; INIT STATE, PACKET-NUMBER, NUMTRY
  1335.               ;(*PACKET-NUMBER* 0)
  1336.               ;(*NUMTRY* 0)
  1337.               (BUFEMP-IGNORE-LINE-FEED NIL)       ; KLUDGE, SO CR/LF TRANSLATES RIGHT.
  1338.               (*PACKCOUNT-WRAPAROUND* 0)
  1339.               (*bytecount* (if (eq *state* #\R) nil 0))
  1340.               (bps 0.))
  1341.           (LOOP                                             ; DO AS LONG AS NECESSARY
  1342.             WHEN *DEBUG* DO
  1343.             (DEBUGGER-TELL-USER ':RECSW)
  1344.             DO
  1345.  
  1346.             (OR *REMOTE* (GIVE-STATE-INFO *STATE* *PACKET-NUMBER* *NUMTRY*))
  1347.             (COND ((EQ (SEND TERMINAL-IO ':TYI-NO-HANG) #\CONTROL-Z)
  1348.                      (SETQ *STATE* #\A)
  1349.                      (FORMAT INTERACTION-PANE "...~C~% Aborting file transfer." #\CONTROL-Z)))
  1350.             (SELECTQ *STATE*
  1351.               (#\R (SETQ *STATE* (RINIT)))        ;  R RECEIVE INIT
  1352.               (#\F (SETQ *STATE* (RFILE)))        ;  F RECEIVE FILE HEADER
  1353.               (#\D (SETQ *STATE* (RDATA)))        ;  D RECEIVE DATA
  1354.               (#\C (RETURN *TRUE*))               ;  C DONE, COMPLETE
  1355.               (#\A (RETURN *FALSE*))              ;  A ABORT
  1356.               (:OTHERWISE (RETURN *FALSE*)))))    ;  T DONE FAIL
  1357.  
  1358.     (COND (*FP* (SEND *FP* ':CLOSE *FILE-CLOSING-DISPOSITION*)
  1359.                     (SETQ *FP* NIL))))            ; MAKE SURE NO FILES ARE HANGING OPEN
  1360.   )
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372. ;;; @@@ RINIT
  1373.  
  1374. (DEFUN RINIT ()
  1375.   "receive initialization."
  1376.   (COND ((> *NUMTRY* *MAXTRY*) #\A)
  1377.           (T (INCF *NUMTRY*)
  1378.              (MULTIPLE-VALUE-BIND (TYPE NUM LEN DATA) (RPACK)
  1379.                NUM LEN; COMPILER
  1380.                (COND ((= TYPE #\S)
  1381.                         (RPAR DATA)
  1382.                         (SETQ DATA (SPAR DATA))
  1383.                         (SPACK #\Y *PACKET-NUMBER* 6 DATA)
  1384.                         (SETQ *OLDTRY* *NUMTRY*)
  1385.                         (SETQ *NUMTRY* 0)
  1386.                         (BUMP-PACKET-NUMBER)
  1387.                         #\F)
  1388.                        ((ERRP TYPE) (PRERRPKT DATA) #\A)
  1389.                        ((FAILP TYPE)
  1390.                         (WARN-USER "sinit failed: sending a NAK.")
  1391.                         (SPACK #\N *PACKET-NUMBER* 0 NIL)
  1392.                         *STATE*)
  1393.                        (T #\A))))))
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399.  
  1400.  
  1401. ;;; @@@ RFILE
  1402.  
  1403.  
  1404.  
  1405. (DEFUN RFILE (&AUX OURFILENAME)
  1406.   (COND ((> *NUMTRY* *MAXTRY*) #/A)
  1407.           (T (INCF *NUMTRY*)
  1408.              (MULTIPLE-VALUE-BIND (TYPE NUM LEN PACKET) (RPACK)
  1409.                LEN                                ; COMPILER
  1410.                (COND ((= TYPE #\S)
  1411.                         ;;; SEND INIT
  1412.                         (COND ((> *OLDTRY* *MAXTRY*) #\A)
  1413.                                 (T (INCF *OLDTRY*)
  1414.                                    (COND ((= NUM (IF (= *PACKET-NUMBER* 0) #o77 (1- *PACKET-NUMBER*)))
  1415.                                             (SETQ PACKET (SPAR PACKET))
  1416.                                             (SPACK #\Y NUM 6 PACKET)
  1417.                                             (SETQ *NUMTRY* 0)
  1418.                                             *STATE*)
  1419.                                            (T #\A)))))
  1420.                        ((= TYPE #\Z)
  1421.                         ;;; END OF FILE
  1422.                         (COND ((> *OLDTRY* *MAXTRY*) #\A)
  1423.                                 (T (INCF *OLDTRY*)
  1424.                                    (COND ((= NUM (IF (= *PACKET-NUMBER* 0) #o77 (1- *PACKET-NUMBER*)))
  1425.                                             (SPACK #\Y NUM 0 NIL)
  1426.                                             (SETQ *NUMTRY* 0)
  1427.                                             *STATE*)
  1428.                                            (T #\A)))))
  1429.                        ((= TYPE #\F)
  1430.                         ;;; FILE HEADER
  1431.                         (COND ((NOT (= NUM *PACKET-NUMBER*))
  1432.                                  #\A)
  1433.                                 (T
  1434.                  ;1; This seems to screw up wildcard server/receives...
  1435.                  ;1; Also, it doesn't make much sense to me to have it here.
  1436.                  #-3600
  1437.                  (SETQ OURFILENAME (or (prog1 *as-filnam*
  1438.                                   (setq *as-filnam* nil))
  1439.                                (STRING-FOR-KERMIT-OUTFILE PACKET))
  1440.                        )
  1441.                  #+3600
  1442.                  (SETQ OURFILENAME (STRING-FOR-KERMIT-OUTFILE PACKET))
  1443.                 
  1444.                                    (COND ((SETQ *FP* (OPEN-FILE-OUT-OR-NOT OURFILENAME))
  1445.                                             (FORMAT INTERACTION-PANE "~&Receiving ~A as ~A"
  1446.                                                       PACKET
  1447.                                                       OURFILENAME)
  1448.                                             (OR *REMOTE* (UPDATE-STATUS-LABEL OURFILENAME NIL))
  1449.                                             (SPACK #\Y *PACKET-NUMBER* 0 NIL)
  1450.                                             (SETQ *OLDTRY* *NUMTRY*)
  1451.                                             (SETQ *NUMTRY* 0)
  1452.                                             (BUMP-PACKET-NUMBER)
  1453.                                             (SETQ DATA-XFER-START-TIME (TIME)
  1454.                                                     *BYTECOUNT* 0)
  1455.                                             #\D)
  1456.                                            (T (FORMAT INTERACTION-PANE "~&Cannot create ~S" PACKET)
  1457.                                                             ;experimental error packet sending--mhd
  1458.                                               (SPACK #\E *PACKET-NUMBER* 45     ;
  1459.                                                        "kermit-q: Error in receiving file header.")
  1460.                                               #\A)))))
  1461.                        ((= TYPE #\B)
  1462.                         ;;; END OF TRANSMISSION
  1463.                         (COND ((NOT (= NUM *PACKET-NUMBER*)) #\A)
  1464.                                 (T (SPACK #\Y *PACKET-NUMBER* 0 NIL) #\C)))
  1465.                        ((ERRP TYPE)
  1466.                         ;;; ERROR
  1467.                         (PRERRPKT PACKET)
  1468.                         #\A)
  1469.                        ((FAILP TYPE)
  1470.                         ;;; FAILURE
  1471.                         (SPACK #\N *PACKET-NUMBER* 0 NIL)
  1472.                         *STATE*)
  1473.                        (T #\A))))))
  1474.  
  1475.  
  1476.  
  1477.  
  1478.  
  1479. ;;; @@@ rdata
  1480.  
  1481. (DEFUN RDATA ()
  1482.   (COND ((> *NUMTRY* *MAXTRY*) #\A)
  1483.           (T (INCF *NUMTRY*)
  1484.              (MULTIPLE-VALUE-BIND (TYPE NUM LEN DATA) (RPACK)
  1485.                (COND ((= TYPE #\D)
  1486.                         (COND ((NOT (= NUM *PACKET-NUMBER*))
  1487.  
  1488.                                  (COND ((> *OLDTRY* *MAXTRY*) #\A)
  1489.                                          (T (INCF *OLDTRY*)
  1490.                                             (COND
  1491.                                               ((= NUM (IF (= *PACKET-NUMBER* 0)
  1492.                                                               77 (1- *PACKET-NUMBER*)))
  1493.                                                (SPACK #\Y NUM 6 DATA)
  1494.                                                (SETQ *NUMTRY* 0)
  1495.                                                *STATE*)
  1496.                                               (T #\A)))))
  1497.                                 (T  ;; OK, GOT DATA WITH RIGHT PACKET NUMBER.
  1498.  
  1499.                                  (BUFEMP DATA LEN)
  1500.                                  (SETQ *BYTECOUNT* (+ LEN *BYTECOUNT*))
  1501.                                  (SPACK #\Y *PACKET-NUMBER* 0 NIL)
  1502.                                  (SETQ *OLDTRY* *NUMTRY*)
  1503.                                  (SETQ *NUMTRY* 0)
  1504.                                  (BUMP-PACKET-NUMBER)
  1505.                                  #\D )))
  1506.                        ((= TYPE #\F)
  1507.                         (COND ((> *OLDTRY* *MAXTRY*) #\A)
  1508.                                 (T (INCF *OLDTRY*)
  1509.                                    (COND ((= NUM (IF (= *PACKET-NUMBER* 0)
  1510.                                                          77 (1- *PACKET-NUMBER*)))
  1511.                                             (SPACK #\Y NUM 0 NIL)
  1512.                                             (SETQ *NUMTRY* 0)
  1513.                                             *STATE*)
  1514.                                            (T #\A)))))
  1515.                        ((= TYPE #\Z)
  1516.                         (COND ((NOT (= NUM *PACKET-NUMBER*))
  1517.                                  #\A)
  1518.                                 (T (SPACK #\Y *PACKET-NUMBER* 0 NIL)
  1519.                                    (FORMAT INTERACTION-PANE
  1520.                                              "~% File received successfully: ~A~%"
  1521.                                              (SEND *FP* ':TRUENAME))
  1522.                                    (send *fp* ':close)
  1523.                                    (and current-file-props-list       ;temp hacks
  1524.                                           (lexpr-funcall #'fs:change-file-properties
  1525.                                                              (send *fp* ':truename)
  1526.                                                               'error-yes current-file-props-list))
  1527.  
  1528.                                    (PUSH (LIST (SEND *FP* ':TRUENAME) (TIME) ':RECEIVE)
  1529.                                            *SUCCESSFUL-TRANSACTIONS*)
  1530.                                    (SEND *FP* ':CLOSE)
  1531.                                    (BUMP-PACKET-NUMBER)
  1532.                                    #\F)))
  1533.                        ((ERRP TYPE)
  1534.                         (PRERRPKT DATA)
  1535.                         #/A)
  1536.                        ((FAILP TYPE)
  1537.                         (SPACK #\N *PACKET-NUMBER* 0 NIL)
  1538.                         *STATE*)
  1539.                        (T #\A))))))
  1540.  
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550. ;;; @@@ SPACK
  1551.   ;; TYPE -- a number, the type of packet this is.
  1552.   ;; NUM  -- a number, the the packet-number of this packet.
  1553.   ;; LEN  -- a number, the length of the packet.
  1554.   ;; DATA -- a string, i.e. an art-string type of array, the data of this pkt.
  1555.  
  1556. (defun spack (type num len data)
  1557.   "send a packet..."
  1558.  
  1559.   (let ((chksum 0)
  1560.           (buffer *string-array-buffer*)
  1561.           (index 0)
  1562.           (temp nil))
  1563.  
  1564.     (and *debug* (debugger-tell-user ':spack type num len data))
  1565.  
  1566.     ;; issue any padding:
  1567.     (loop for i from 0 below *pad*
  1568.             do
  1569.              (setf (aref buffer index) *padchar*)
  1570.              (incf index))
  1571.  
  1572.     ;; issue packet marker (ascii 1, soh):
  1573.     (setf (aref buffer index) *soh*)
  1574.     (incf index)
  1575.  
  1576.     ;; issue char count & update checksum:
  1577.     (setf (aref buffer index) (setq temp (tochar (+ len 3))))
  1578.     (incf index)
  1579.     (incf chksum temp)
  1580.  
  1581.     ;; issue packet-number & update checksum:
  1582.     (setf (aref buffer index) (setq temp (tochar num)))
  1583.     (incf index)
  1584.     (incf chksum temp)
  1585.  
  1586.     ;; issue the packet type & update checksum:
  1587.     (setf (aref buffer index) type)
  1588.     (incf index)
  1589.     (incf chksum type)
  1590.  
  1591.     ;; issue all the data & update checksum (as we go):
  1592.     (and data (loop for i from 0 below len
  1593.                         as ch = (aref data i)    ;1; this seems a bit strange... missing DO?
  1594.                 #+3600 DO        ;1; I added it for 3600...
  1595.                         (setf (aref buffer index) ch)
  1596.                         (incf index)
  1597.                         (incf chksum ch)))
  1598.  
  1599.     ;; compute & issue the final checksum:
  1600.     (setf (aref buffer index) (tochar (compute-final-checksum chksum)))
  1601.     (incf index)
  1602.  
  1603.     ;; issue an extra-packet line terminator:
  1604.     (setf (aref buffer index) *eol*)
  1605.     (incf index)
  1606.     (setf (fill-pointer buffer) index)
  1607.  
  1608.     ;;; packet is alive and well and living in buffer;
  1609.     ;;; so release it now:
  1610.     (and *debug* (debugger-tell-user ':spack-line buffer))
  1611.     (send *ttyfd* ':string-out buffer 0 index)
  1612.     nil))
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618.  
  1619.  
  1620.  
  1621.  
  1622.  
  1623.  
  1624.  
  1625. ;;; @@@ RPACK
  1626.     ;;; values returned are in order:
  1627.     ;;; TYPE, NUM, LEN, DATA
  1628.     ;;; type -- a character (fixnum), in {#\A, #\S, ...}, for ex., which means "abort".
  1629.     ;;; num  -- a number, the packet-number of this packet.
  1630.     ;;; len  -- a number, the number of characters in this packet.
  1631.     ;;; data -- a string, the data of this packet, which is as many
  1632.     ;;;             characters as appropriate/desired for this type of packet.
  1633. ;;;  many callers need only one (usually the type) value.
  1634.  
  1635. (defun rpack ()
  1636.   "receive other kermit's packet, which should be a string
  1637. of xxxnxxx to xxxn+mxxx characters. each character means.."
  1638.  
  1639. ;;; Still need: 2-char checksum handling to be added in other parts.
  1640.  
  1641.   (prog (ch type rchksum len num
  1642.            (data *recpkt*)
  1643.            (time? (and (memq ':tyi-with-timeout (send *ttyfd* ':which-operations))
  1644.                          (* 60. (if (< *timint* *mintim*) *mintim* *timint*))))
  1645.            (cchksum 0)
  1646.            stage
  1647.            (tyi-operation (cond ((memq ':tyi-with-timeout (send *ttyfd* ':which-operations))
  1648.                                      ':tyi-with-timeout)
  1649.                                     (t ':tyi))))
  1650.      continue
  1651.      (loop for ch = (send *ttyfd* tyi-operation time?)
  1652.              if (not ch) do (and (setq stage 'soh) (go timeout))
  1653.              until (= (logand ch 0177) *soh*))    ; WAIT FOR SOH.
  1654.  
  1655.      (setq ch (send *ttyfd* tyi-operation time?))
  1656.      (if (not ch) (and (setq stage 'len) (go timeout)))
  1657.      (if (not *image*) (setq ch (logand ch 0177)))
  1658.      (if (= ch *soh*) (go continue))
  1659.      (setq cchksum ch)                                      ;OK, START CHECKSUM
  1660.      (setq len (- (unchar ch) 3))                 ;GET CHARACTER COUNT
  1661.  
  1662.      (cond ((or (< len 0) (> len (- *maxpacksiz* 3)))
  1663.               (go fatal-error)))                            ;bad error, happens alot, when other kermit
  1664.                                                             ;is at command level instead of waiting for
  1665.                                                             ;packets.
  1666.  
  1667.      (setq ch (send *ttyfd* tyi-operation time?))
  1668.      (if (not ch) (and (setq stage 'num) (go timeout)))
  1669.      (if (not *image*) (setq ch (logand ch 0177)))
  1670.      (if (= ch *soh*) (go continue))
  1671.      (incf cchksum ch)                                      ;OK, UPDATE CHECKSUM
  1672.      (setq num (unchar ch))                       ;GET PACKET NUMBER
  1673.  
  1674.  
  1675.      (setq ch (send *ttyfd* tyi-operation time?))
  1676.      (if (not ch) (and (setq stage 'type) (go timeout)))
  1677.      (if  (not *image*) (setq ch (logand ch 0177)))
  1678.      (if (= ch *soh*) (go continue))
  1679.      (incf cchksum ch)                                      ;OK, UPDATE CHECKSUM
  1680.      (setq type ch)                               ;GET PACKET TYPE
  1681.  
  1682.      (loop for i from 0 below len
  1683.              doing (progn (setq ch (send *ttyfd* tyi-operation time?))
  1684.                               (if (not ch) (and (setq stage 'data) (go timeout)))
  1685.                               (if (not *image*) (setq ch (logand ch 0177)))
  1686.                               (if (= ch *soh*) (go continue))
  1687.                               (incf cchksum ch)   ;OK, UPDATE CHECKSUM
  1688.                               (setf (aref data i) ch))      ;GET DATA CHARACTER
  1689.  
  1690.              finally (progn (setf (aref data len) 0)        ;MARK THE END OF THE DATA
  1691.                                 (setf (fill-pointer data) len)))
  1692.  
  1693.      (setq ch (send *ttyfd* tyi-operation time?))
  1694.      (if (not ch) (and (setq stage 'rchksum) (go timeout)))
  1695.      (setq rchksum (unchar ch))                             ;OK, GET LAST CHARACTER (CHECKSUM)
  1696.      (cond  ((eq *checksum-type* 2)
  1697.                (setq ch (send *ttyfd* tyi-operation time?))
  1698.                (if (not ch) (and (setq stage 'rchksum) (go timeout)))
  1699.                (setq rchksum (cons rchksum (unchar ch))))   ;ok, make a two ch checksum maybe.
  1700.               ((eq *checksum-type* 3) (ferror nil "Only 1 or 2 character checksums are supported."))
  1701.               ((not (memq *checksum-type* '(1 2)))
  1702.                (ferror nil "Bad value for *checksum-type*: ~A is not a legal type;~
  1703.                                 ~%value can only be 1 or 2."
  1704.                          *checksum-type*)))
  1705.  
  1706.      (setq ch (send *ttyfd* tyi-operation time?))
  1707.      (if (not ch) (and (setq stage 'eol) (go timeout)))
  1708.      (if (not *image*) (setq ch (logand ch 0177)))
  1709.      (if (= ch *soh*) (go continue))              ;OK, GET EOL CHAR AND TOSS IT
  1710.                                                             ;SAFE!
  1711.      (and *debug* (debugger-tell-user ':rpack type num len data))
  1712.  
  1713.      (setq cchksum (selectq *checksum-type*
  1714.                          (1 (compute-final-checksum cchksum))
  1715.                          (2 (compute-2-char-checksum cchksum))))
  1716.  
  1717.      (if (not (equal cchksum rchksum))
  1718.            (progn (warn-user "RPACK received bad checksum [~A//~A]"
  1719.                                  rchksum cchksum)
  1720.                     ;; corruption, oh no!
  1721.                     (return (values *false* num len data)))
  1722.        ;; else checksum ok, 'uncorrupted'.
  1723.        (return (values type num len data)))
  1724.    timeout
  1725.      (warn-user "RPACK timed out waiting for ~A character." stage)
  1726.      (return *false*)
  1727.    fatal-error
  1728.      ;; should send error packet, when that can be done.
  1729.      (warn-user "RPACK received illegal packet length spec: ~D" len)
  1730.      (return *false*)))
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741. ;;; @@@ spar packet
  1742.  
  1743. (DEFUN SPAR (PACKET)
  1744.   "Fill the data array with my send-init parameters."
  1745.   (SETF (FILL-POINTER PACKET) 6)
  1746.   (SETF (AREF PACKET 0) (TOCHAR *MAXPACKSIZ*))
  1747.   (SETF (AREF PACKET 1) (TOCHAR *MYTIME*))
  1748.   (SETF (AREF PACKET 2) (TOCHAR *MYPAD*))
  1749.   (SETF (AREF PACKET 3) (CTL *MYPCHAR*))
  1750.   (SETF (AREF PACKET 4) (TOCHAR *MYEOL*))
  1751.   (SETF (AREF PACKET 5) *MYQUOTE*)
  1752.   PACKET)
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761. ;;; @@@ rpar
  1762.  
  1763. (DEFUN RPAR (DATA)
  1764.   "Get the other hosts send-init parameters."
  1765.   (SETF (FILL-POINTER DATA) 6)
  1766.   (SETQ *SPSIZ* (UNCHAR (AREF DATA 0)))
  1767.   (SETQ *TIMINT* (UNCHAR (AREF DATA 1)))
  1768.   (SETQ *PAD* (UNCHAR (AREF DATA 2)))
  1769.   (SETQ *PADCHAR* (CTL (AREF DATA 3)))
  1770.   (SETQ *EOL* (UNCHAR (AREF DATA 4)))
  1771.   (SETQ *QUOTE* (AREF DATA 5))
  1772.   DATA)
  1773.