[comp.sources.games] v11i016: tinyclients - three clients for tinyMUD, Part02/03

billr@saab.CNA.TEK.COM (Bill Randle) (08/01/90)

Submitted-by: James Aspnes <asp@cs.cmu.edu>
Posting-number: Volume 11, Issue 16
Archive-name: tinyclients/Part02



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 3)."
# Contents:  tinymud.el tinytalk/command.c tinytalk/fred.c
#   tinytalk/tinytalk.doc
# Wrapped by billr@saab on Fri Jul 27 15:45:15 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'tinymud.el' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tinymud.el'\"
else
echo shar: Extracting \"'tinymud.el'\" \(15255 characters\)
sed "s/^X//" >'tinymud.el' <<'END_OF_FILE'
X;;; Major Mode for talking to TinyMUD
X;;; by James Aspnes (asp@cs.cmu.edu) and Stewart Clamen (clamen@cs.cmu.edu)
X;;; 1989, 1990
X
X(defvar tinymud-server "daisy.learning.cs.cmu.edu"
X  "*Host with running tinymud game.")
X
X(defvar tinymud-port 4201
X  "*Port to connect to on tinymud-server.")
X
X(defvar tinymud-name "TinyMUD"
X  "*Name of TinyMUD server to connect to.")
X
X(defvar tinymud-prompt ?>
X  "Prompt character for TinyMUD mode.")
X
X(defvar tinymud-page-regexp "You sense that [^ ]* is looking for you in "
X  "Regular expression for detecting pages.")
X
X(defvar tinymud-connection-error-string
X  "Either that player does not exist, or has a different password.")
X
X(defvar tinymud-show-page nil
X  "*If non-nil, pop up tinymud buffer whenever a page arrives.")
X
X(defvar tinymud-reconnect-regexp
X  "#### Please reconnect to \\([^@]*\\)@\\([^ @]*\\) *\\(\\|([^ @]*)\\) port \\([0-9]+\\) ####.*$"
X  "Regular expression for detecting reconnect signals.")
X
X(defconst tinymud-new-connectionp nil
X  "Flag to identify hail for new connection")
X
X(defvar tinymud-accept-reconnects nil
X  "*If nil, reject reconnect signals. If non-nil, accept reconnect signals 
Xby breaking existing connection and establishing new connection.  If an
Xinteger, spawn <n> connections before breaking any.")
X
X(defun tinymud-check-reconnect ()
X  "Look for reconnect signal and open new connection if non to that
Xsite already exists."
X  (goto-char (point-min))
X  (while (not (eobp))
X    (if (and tinymud-accept-reconnects (looking-at tinymud-reconnect-regexp))
X	(let ((tinymud-name (buffer-substring (match-beginning 1)
X					      (match-end 1)))
X	      (tinymud-server-addr (buffer-substring (match-beginning 2)
X						     (match-end 2)))
X	      (tinymud-server (and (not (eq (match-beginning 3)
X					    (match-end 3)))
X				   (buffer-substring (1+ (match-beginning 3))
X						     (1- (match-end 3)))))
X	      (tinymud-port (string-to-int
X			     (buffer-substring (match-beginning 4)
X					       (match-end 4)))))
X	  (delete-region (match-beginning 0) (match-end 0))
X	  (let* ((tinymud-buffer-name (concat "*" tinymud-name "*"))
X		 (tinymud-buffer-process
X		  (get-buffer-process tinymud-buffer-name)))
X
X	    (cond
X	     (tinymud-buffer-process ; No existing connection to that site...
X	      (message "Connection to that site already established."))
X	     ((not tinymud-server)
X	      (message "GNU Emacs cannot handle nonsymbolic names.  Sorry."))
X	     ((zerop tinymud-port)
X	      (message "Illformed portal signal. Inform Builder."))
X	     (t
X	      (save-excursion
X		(setq tinymud-new-connectionp tinymud-buffer-name)
X		(tinymud t)))))))
X    (beginning-of-line 2)))
X
X
X(defun tinymud-check-page ()
X  "Look for page message, and pop-up buffer if specified."
X  (goto-char (point-min))
X  (while (not (eobp))
X    (if (and tinymud-show-page (looking-at tinymud-page-regexp))
X	(progn
X	  (display-buffer (current-buffer))
X	  (message "You are being paged in %s"
X		   (buffer-name (current-buffer)))))
X    (beginning-of-line 2)))
X
X
X(defun tinymud-fill-lines ()
X  "Fill buffer line by line."
X  (goto-char (point-min))
X  (while (not (eobp))
X    (let ((break (move-to-column (1+ fill-column))))
X      (if (<= break fill-column)
X	  (beginning-of-line 2)
X	;; else fill
X	(skip-chars-backward "^ \n")
X	(if (bolp)
X	    ;; can't fill, we lose
X	    (beginning-of-line 2)
X	  (delete-horizontal-space)
X	  (insert ?\n))))))
X
X(defvar tinymud-filter-hook
X  '(tinymud-check-reconnect tinymud-check-page tinymud-fill-lines)
X  "*List of functions to call on each line of tinymud output.  The
Xfunction is called with no arguments and the buffer narrowed to just
Xthe line.") 
X
X(defun tinymud-filter (proc string)
X  "Filter for input from TinyMUD process.  Also, if recently
Xestablished new connection automatically, check to see if number
Xof active connections exceeded connection limit and delete current
Xprocess if so."
X  (save-excursion
X    (set-buffer (process-buffer proc))
X    (goto-char (marker-position (process-mark proc)))
X    (let ((start (point)))
X      (insert-before-markers string)
X      (let ((end (point)))
X	(subst-char-in-region start end ?\^m ?\  t)
X	(goto-char start)
X	(beginning-of-line nil)
X	(save-restriction
X	  (narrow-to-region (point) end)
X	  ;; call tinymud-filter-hook
X	  (run-hooks 'tinymud-filter-hook)
X	  (if (process-mark proc)
X	      (set-marker (process-mark proc) (point-max)))))))
X  (if tinymud-new-connectionp
X      (progn
X	(if (or			     ; Do we close current connection?
X	     (not (numberp tinymud-accept-reconnects))
X	     (let ((c tinymud-accept-reconnects) (l (process-list)))
X	       (while l
X		 (if (and (eq (process-filter (car l)) 'tinymud-filter)
X			  (eq (process-status (car l)) 'run))
X		     (setq c (1- c)))
X		 (setq l (cdr l)))
X	       (< c 0)))
X	    (progn
X	      (delete-process (get-buffer-process (current-buffer)))
X	      (kill-buffer (current-buffer))))
X	(progn
X	  (pop-to-buffer tinymud-new-connectionp)
X	  (if (> (baud-rate) search-slow-speed) (recenter))
X	  (setq tinymud-new-connectionp nil)))))
X
X
X
X(defun tinymud-connect-filter (proc string)
X  "Filter for connecting to a TinyMUD server.  Replaced with tinymud-filter
Xonce successful."
X  (if (not (string-equal string tinymud-connection-error-string))
X      (set-process-filter proc 'tinymud-filter)))
X
X(defun tinymud-send ()
X  "Send current line of input to TinyMUD."
X  (interactive)
X  (let ((proc (get-buffer-process (current-buffer))))
X    (cond ((or (null proc)
X	       (not (eq (process-status proc) 'open)))
X	   (message "Not connected--- nothing sent.")
X	   (insert ?\n))
X	  (t
X	   ;; process exists, send line
X	   ;; moving to end of current line first
X	   (beginning-of-line 1)
X	   (let ((start (max (process-mark proc) (point))))
X	     (if (equal (char-after start) tinymud-prompt)
X		 (setq start (1+ start)))
X	     (goto-char start)
X	     (end-of-line 1)
X	     (send-region proc start (point))
X	     (send-string proc "\n")
X	     (goto-char (point-max))
X	     (insert ?\n)
X	     (move-marker (process-mark proc) (point))
X	     (insert tinymud-prompt))))))
X
X(defun tinymud-quit ()
X  "Quit TinyMUD process."
X  (interactive)
X  (if (yes-or-no-p "Are you sure you want to quit tinymud?")
X      (delete-process (get-buffer-process (current-buffer)))))
X
X(defvar tinymud-mode-map
X  (let ((map (make-sparse-keymap)))
X    (define-key map "\n" 'tinymud-realign-and-send)
X    (define-key map "\r" 'tinymud-send)
X    (define-key map "\^c\^c" 'tinymud-quit)
X    (define-key map "\^c\^m" 'tinymud-macro-command)
X    map)
X  "Keymap for tinymud-mode.")
X
X(defun tinymud-mode ()
X  "Major Mode for talking to inferior TinyMUD processes.
X
XCommands: 
X\\{tinymud-mode-map}
XVariables: [default in brackets]
X
X tinymud-server					[\"daisy.learning.cs.cmu.edu\"]
X    Symbolic host name of TinyMUD server.  
X tinymud-port					[4201]
X    (Integer) port number of TinyMUD server.
X tinymud-name					[\"TinyMUD\"]
X    (String) name for TinyMUD server.  
X tinymud-show-page				[nil]
X    If non-nil, pop up tinymud buffer whenever a page arrives.
X tinymud-accept-reconnects			[nil]
X    If nil, reject reconnect signals. If non-nil, accept reconnect
X    signals by breaking existing connection and establishing new
X    connection.  If an integer, spawn that many connections before
X    breaking any.
X tinymud-filter-hook 
X    List of hooks to call before displaying output from TinyMUD
X    process to tinymud buffer.  [Default hooks support line-filling,
X    page checking, and reconnect detection.]
X tinymud-macro-commands-alist			['(\"nil\" . \"\")]
X    Alist of commands macros.  
X tinymud-macro-commands-file			[\"~/.tinymud_macros\"]
X    Pathname to file containing command macros (written in
X    emacs-lisp).  Should SETQ tinymud-macro-commands-alist.
X tinymud-passwd-file				[\"~/.tinymud\"]
X    Pathname to location of TinyMUD character/password file. 
X tinymud-mode-hook				[nil]
X    Hook to run at startup.  Users wishing to use macros may want to
X    bind it to the following in their .emacs file:
X
X     (setq tinymud-mode-hook
X           '(lambda ()
X    	  (tinymud-load-macro-commands tinymud-macro-commands-file)))
X
X"
X  (interactive)
X  (kill-all-local-variables)
X  (setq mode-name "TinyMUD")
X  (setq major-mode 'tinymud-mode)
X  (set-syntax-table text-mode-syntax-table)
X  (use-local-map tinymud-mode-map)
X  (make-local-variable 'mode-line-process)
X  (let* ((s (and (concat "@" tinymud-server)))
X	 (ss (cond ((not tinymud-accept-reconnects) "")
X		   (t (if (> (length s) 20) (substring s 0 20) s)))))
X    (setq mode-line-process (list (concat ss ":%s"))))
X  (make-local-variable 'tinymud-filter-hook)
X  (run-hooks 'tinymud-mode-hook))
X
X(defun tinymud (&optional autoconnect)
X  "Connect to TinyMUD.  
X
XConnects to a tinymud server defined by the variables tinymud-server, 
Xtinymud-port, and tinymud-name.
X
XWith optional argument, look in tinymud-passwd-file 
Xfor name to connect with and attempt connect."
X  (interactive "P")
X  (let* ((buf (get-buffer-create (concat "*" tinymud-name "*")))
X	 (proc (get-buffer-process buf)))
X    (if (and proc (eq (process-status proc) 'open))
X	(switch-to-buffer buf)
X      ;; else we have to start it
X      (if proc (delete-process proc))
X      (let ((proc (open-network-stream "TinyMUD" buf
X				       tinymud-server tinymud-port)))
X	(if autoconnect
X	    (let ((entry (tinymud-read-entry tinymud-name)))
X	      (set-process-filter proc 'tinymud-connect-filter)
X	      (tinymud-send-string
X	       (mapconcat '(lambda (x) x) (cons "connect" entry) " ")
X	       proc)))
X	(set-process-filter proc 'tinymud-filter)	    
X	(switch-to-buffer buf)
X	(goto-char (point-max))
X	(set-marker (process-mark proc) (point))
X	(insert tinymud-prompt)
X	(tinymud-mode)
X	))))
X			   
X;;; Macro Commands
X
X(defvar tinymud-current-process nil
X  "Current TinyMUD process")
X
X(defvar tinymud-macro-expansion-mode-map
X  (let ((map (make-sparse-keymap)))
X    (define-key map "\^c\^c" 'tinymud-macro-send)
X    (define-key map "\^c\^s" 'tinymud-macro-send)
X    (define-key map "\^c\^]" 'tinymud-macro-abort)
X    (define-key map "\^c\^d" 'tinymud-macro-define)
X    map)
X  "Keymap for tinymud-macro-expansion-mode.")
X
X(defun tinymud-macro-expansion-mode ()
X  "Major Mode for mucking with TinyMUD macro expansion.
XCommands:
X\\{tinymud-macro-expansion-mode-map}
X"
X  (interactive)
X  (kill-all-local-variables)
X  (setq mode-name "TinyMUD-Macro-Expansion")
X  (setq major-mode 'tinymud-macro-expansion-mode)
X  (set-syntax-table text-mode-syntax-table)
X  (use-local-map tinymud-macro-expansion-mode-map)
X  (make-local-variable 'tinymud-expansion-macro-name)
X  (make-local-variable 'tinymud-current-process)
X  (message "Use ^C^C to send, ^C^] to abort..."))
X
X(defun tinymud-macro-define (name)
X  "Define buffer as tinymud-macro."
X  (interactive (list (completing-read "MUD Macro: "
X				      tinymud-macro-commands-alist
X				      nil nil
X				      tinymud-expansion-macro-name)))
X  (let ((oldval (assoc name tinymud-macro-commands-alist)))
X    (if oldval
X	(setcdr oldval (buffer-string))
X      (setq 
X       tinymud-macro-commands-alist
X       (cons
X	(cons name (buffer-string))
X	tinymud-macro-commands-alist))))
X  (if (y-or-n-p "Save to file? ")
X      (tinymud-store-macro-commands
X       (expand-file-name
X	(read-file-name (concat "File to save to (default "
X				tinymud-macro-commands-file
X				"): ")
X			"~/"
X			tinymud-macro-commands-file)))))
X
X
X(defun tinymud-macro-abort ()
X  "Abort macro expansion buffer."
X  (interactive)
X  (kill-buffer (current-buffer))
X  (delete-window))
X
X(defun tinymud-macro-send ()
X  "Abort macro expansion buffer."
X  (interactive)
X  (let ((str (buffer-string))
X	(proc tinymud-current-process))
X    (tinymud-macro-abort)
X    (tinymud-send-string str proc)))
X
X(defvar tinymud-macro-commands-alist (list (cons "nil" ""))
X  "*Alist of macros (keyed by strings)")
X
X(defun tinymud-send-string (string proc)
X  "Send STRING as input to PROC"
X  (send-string proc (concat string "\n")))
X
X(defvar tinymud-macro-commands-file "~/.tinymud_macros"
X  "*Pathname of tinymud macros.")
X
X(defun tinymud-load-macro-commands (filename)
X  "Load file of tinymud-macros"
X  (if (file-exists-p filename)
X      (progn
X	(setq tinymud-macro-commands-file filename)
X	(load-file filename))
X    (setq tinymud-macro-commands-alist '("nil" . ""))))
X
X(defun tinymud-store-macro-commands (filename)
X  "Store tinymud-macros in filename"
X  (interactive "FFile to save to: ")
X  (setq tinymud-macro-commands-file filename)
X  (save-excursion
X    (let ((tmp (get-buffer-create " *Macros to write*")))
X      (set-buffer tmp)
X      (erase-buffer)
X      (insert "(setq tinymud-macro-commands-alist '\n"
X	      (prin1-to-string tinymud-macro-commands-alist)
X	      ")")
X      (write-file filename))))
X
X
X
X
X
X(defun tinymud-macro-command (arg)
X  "Insert into stream one of the commands in tinymud-macro-commands-alist.
XWithout command argument, opens buffer for editting.  With argument
Xsends alist entry directly to process."
X  (interactive "P")
X  (let ((macro
X	 (assoc
X	  (or (if (stringp arg) arg)
X	      (completing-read "MUD Macro: "
X			       tinymud-macro-commands-alist nil t nil))
X	  tinymud-macro-commands-alist)))
X    (let ((match (car macro))
X	  (stuff (cdr macro)))
X      (if (stringp stuff)
X	  (let ((buff (get-buffer-create "*Expansion*"))
X		(proc (get-buffer-process (current-buffer))))
X	    (if (not arg)
X		(progn
X		  (pop-to-buffer buff)
X		  (erase-buffer)
X		  (insert stuff)
X		  (goto-char (point-min))
X		  (tinymud-macro-expansion-mode)
X		  (setq tinymud-expansion-macro-name match)
X		  (setq tinymud-current-process proc)
X		  )
X	      (tinymud-send-string stuff tinymud-current-process)))))))
X
X(defun tinymud-realign-and-send ()
X  (interactive)
X  (recenter 0)
X  (tinymud-send))
X
X
X;;; Reading from entry file
X
X(defvar tinymud-passwd-file "~/.tinymud"
X  "*Pathname to location of TinyMUD character/password file.")
X
X(defun tinymud-read-entry (site &optional file)
X  "Read tinymud entries from tinymud-passwd-file."
X  (setq file (expand-file-name (or file tinymud-passwd-file)))
X  (let ((entry
X	 (let ((buffer nil)
X	       (obuf (current-buffer))
X	       (match nil))
X	   (unwind-protect
X	       (progn
X		 (setq buffer (generate-new-buffer "mailrc"))
X		 (buffer-flush-undo buffer)
X		 (set-buffer buffer)
X		 (cond ((get-file-buffer file)
X			(insert (save-excursion
X				  (set-buffer (get-file-buffer file))
X				  (buffer-substring (point-min) (point-max)))))
X		       ((not (file-exists-p file)))
X		       (t (insert-file-contents file)))
X		 ;; Don't lose if no final newline.
X		 (goto-char (point-max))
X		 (or (eq (preceding-char) ?\n) (newline))
X		 (goto-char (point-min))
X		 ;; handle "\\\n" continuation lines
X		 (while (not (eobp))
X		   (end-of-line)
X		   (if (= (preceding-char) ?\\)
X		       (progn (delete-char -1) (delete-char 1) (insert ?\ ))
X		     (forward-char 1)))
X		 (goto-char (point-min))
X		 (while (re-search-forward (concat "^" site) nil t)
X		   (re-search-forward "[^ \t]+")
X		   (let* ((name (buffer-substring (match-beginning 0)
X						  (match-end 0)))
X			  (start (progn (skip-chars-forward " \t") (point))))
X		     (end-of-line)
X		     (setq match
X			   (list name (buffer-substring start (point)))))))
X	     (if buffer (kill-buffer buffer))
X	     (set-buffer obuf))
X	   match)))
X    (cond (entry)
X	  ((string-equal site "default") nil)
X	  (t (tinymud-read-entry "default" file)))))
X      
END_OF_FILE
if test 15255 -ne `wc -c <'tinymud.el'`; then
    echo shar: \"'tinymud.el'\" unpacked with wrong size!
fi
# end of 'tinymud.el'
fi
if test -f 'tinytalk/command.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tinytalk/command.c'\"
else
echo shar: Extracting \"'tinytalk/command.c'\" \(13833 characters\)
sed "s/^X//" >'tinytalk/command.c' <<'END_OF_FILE'
X/************************************************************************/
X/* TinyTalk command line processing.					*/
X/*									*/
X/*	Version 1.0 [ 1/25/90] : Initial implementation by ABR.		*/
X/*		1.1 [ 1/26/90] : Added additional commands.		*/
X/*		1.2 [ 1/26/90] : Added additional commands.		*/
X/*		1.3 [ 2/ 2/90] : Yet more commands; use binary search.	*/
X/*		1.4 [ 2/ 5/90] : A few more commands; world switching.	*/
X/*		1.5 [ 2/ 5/90] : Fixed /savehilite | /loadhilite.	*/
X/*									*/
X/************************************************************************/
X
X#include "tl.h"
X#include <stdio.h>
X
Xextern char *index();
Xextern world_rec *find_world(), *get_default_world(), *get_world_header();
X
X  /* There are enough commands now that a hash table or binary search */
X  /* is preferable.  We'll use a binary search.			      */
X
Xint handle_wrap_command(), handle_nowrap_command(), handle_log_command(),
X    handle_nolog_command(), handle_logme_command(), handle_def_command(),
X    handle_undef_command(), handle_savedef_command(), handle_nologme_command(),
X    handle_listdef_command(), handle_loaddef_command(),
X    handle_quiet_command(), handle_noquiet_command(), handle_login_command(),
X    handle_nologin_command(), handle_help_command(), handle_quit_command(),
X    handle_intr_command(), handle_nointr_command(), handle_beep_command(),
X    handle_nobeep_command(), handle_stty_command(), handle_nostty_command(),
X    handle_gag_command(), handle_nogag_command(), handle_savegag_command(),
X    handle_loadgag_command(), handle_listgag_command(),
X    handle_hilite_command(), handle_help2_command(), handle_recall_command(),
X    handle_nohilite_command(), handle_loadhilite_command(),
X    handle_savehilite_command(), handle_listhilite_command(),
X    handle_whisper_command(), handle_nowhisper_command(),
X    handle_listworlds_command(), handle_world_command();
X
Xint handle_macro_command();
X
Xtypedef struct cmd_entry {
X  char *name;
X  int (*func)();
X} cmd_entry;
X
X  /* It is IMPORTANT that the commands be in alphabetical order! */
X
Xstatic cmd_entry cmd_table[] =
X{
X  { "BEEP", handle_beep_command },
X  { "DEF", handle_def_command },
X  { "GAG", handle_gag_command },
X  { "HELP", handle_help_command },
X  { "HELP2", handle_help2_command },
X  { "HILITE", handle_hilite_command },
X  { "INTR", handle_intr_command },
X  { "LISTDEF", handle_listdef_command },
X  { "LISTGAG", handle_listgag_command },
X  { "LISTHILITE", handle_listhilite_command },
X  { "LISTWORLDS", handle_listworlds_command },
X  { "LOADDEF", handle_loaddef_command },
X  { "LOADGAG", handle_loadgag_command },
X  { "LOADHILITE", handle_loadhilite_command },
X  { "LOG", handle_log_command },
X  { "LOGIN", handle_login_command },
X  { "LOGME", handle_logme_command },
X  { "NOBEEP", handle_nobeep_command },
X  { "NOGAG", handle_nogag_command },
X  { "NOHILITE", handle_nohilite_command },
X  { "NOINTR", handle_nointr_command },
X  { "NOLOG", handle_nolog_command },
X  { "NOLOGIN", handle_nologin_command },
X  { "NOLOGME", handle_nologme_command },
X  { "NOQUIET", handle_noquiet_command },
X  { "NOSTTY", handle_nostty_command },
X  { "NOWHISPER", handle_nowhisper_command },
X  { "NOWRAP", handle_nowrap_command },
X  { "QUIET", handle_quiet_command },
X  { "QUIT", handle_quit_command },
X  { "RECALL", handle_recall_command },
X  { "SAVEDEF", handle_savedef_command },
X  { "SAVEGAG", handle_savegag_command },
X  { "SAVEHILITE", handle_savehilite_command },
X  { "STTY", handle_stty_command },
X  { "UNDEF", handle_undef_command },
X  { "WHISPER", handle_whisper_command },
X  { "WORLD", handle_world_command },
X  { "WRAP", handle_wrap_command }
X};
X
X#define NUM_COMMANDS (sizeof(cmd_table) / sizeof(cmd_entry))
X
Xhandle_command(cmd_line, is_config)
X  register char *cmd_line;
X  int is_config;
X{
X  string cmd, args;
X  register char *place;
X  int (*handler)(), (*binary_search())();
X
X  place = index(cmd_line, ' ');
X  if (place == NULL) {
X    strcpy(cmd, cmd_line + 1);		/* Only have command.  Ignore '/'. */
X    args[0] = '\0';
X  }
X  else {
X    *place = '\0';			/* Get rid of the space.... */
X    strcpy(cmd, cmd_line + 1);
X    strcpy(args, place + 1);
X    *place = ' ';			/* Put the space back! */
X  }
X
X  stripstr(cmd);
X  stripstr(args);
X
X  if (cmd[0] == '\0')			/* Empty command, ignore it. */
X    return;
X
X  handler = binary_search(cmd);
X
X  if (handler != NULL)
X    (*handler)(args);
X  else
X    handle_macro_command(cmd, args);	/* Assume it's a macro. */
X}
X
Xint (*binary_search(cmd))()
X  register char *cmd;
X{
X  register int bottom, top, mid, value;
X
X  bottom = 0;
X  top = NUM_COMMANDS - 1;
X
X  while (bottom <= top) {
X    mid = bottom + ((top - bottom) / 2);
X    value = comparestr(cmd, cmd_table[mid].name);
X    if (value == 0)
X      return (cmd_table[mid].func);
X    else if (value < 0)
X      top = mid - 1;
X    else
X      bottom = mid + 1;
X  }
X
X  return (NULL);
X}
X
Xhandle_wrap_command(args)		/* Enable word wrap. */
X  register char *args;
X{
X  if (args[0] == '\0')			/* No arguments */
X    enable_wrap(0);
X  else {
X    if ((args[0] < '0') || (args[0] > '9')) /* Verify starts numeric. */
X      fprintf(stderr,"%% Invalid wrap value %s.\n", args);
X    else
X      enable_wrap(atoi(args));		/* If argument, use it. */
X  }
X}
X
Xhandle_nowrap_command(args)		/* Disable word wrap. */
X  char *args;
X{
X  disable_wrap();
X}
X
Xhandle_log_command(args)		/* Enable logging. */
X  char *args;
X{
X  enable_logging(args);
X}
X
Xhandle_nolog_command(args)		/* Disable logging. */
X  char *args;
X{
X  disable_logging();
X}
X
Xhandle_logme_command(args)		/* Enable input logging. */
X  char *args;
X{
X  enable_logme();
X}
X
Xhandle_nologme_command(args)		/* Disable input logging. */
X  char *args;
X{
X  disable_logme();
X}
X
Xhandle_def_command(args)		/* Define a macro. */
X  register char *args;
X{
X  register char *place;
X  string name, body;
X
X  place = index(args, '=');
X  if (place == NULL) {
X    fprintf(stderr,"%% No '=' in macro definition.\n");
X    return;
X  }
X
X  *place = '\0';
X  strcpy(name, args);
X  strcpy(body, place + 1);
X  stripstr(name);
X  stripstr(body);
X
X  add_macro(name, body);
X}
X
Xhandle_undef_command(args)		/* Undefine a macro. */
X  char *args;
X{
X  remove_macro(args);
X}
X
Xhandle_savedef_command(args)		/* Save macro definitions. */
X  register char *args;
X{
X  if (args[0] == '\0')			/* No filename, use default. */
X    strcpy(args, "~/tiny.macros");
X
X  write_macros(args);
X}
X
Xhandle_macro_command(cmd, args)		/* Invoke a macro. */
X  char *args;
X{
X  string expanded;
X
X  process_macro(cmd, args, expanded);	  /* Expand the body */
X  if (expanded[0] != '\0')		  /* Catch failure (or empty). */
X    transmit(expanded, strlen(expanded)); /* and send it via link. */
X}
X
Xhandle_quiet_command(args)		/* Turn on portal suppression. */
X  char *args;
X{
X  set_quiet();
X}
X
Xhandle_noquiet_command(args)		/* Turn off portal suppression. */
X  char *args;
X{
X  clear_quiet();
X}
X
Xhandle_login_command(args)		/* Turn on automatic login. */
X  char *args;
X{
X  enable_auto_login();
X}
X
Xhandle_nologin_command(args)		/* Turn off automatic login. */
X  char *args;
X{
X  disable_auto_login();
X}
X
Xhandle_help_command(args)		/* Give user some help. */
X  char *args;
X{
X  puts("% Summary of commands:");
X  puts("%   /WRAP      Enables word-wrap mode.");
X  puts("%   /NOWRAP    Disables word-wrap mode.");
X  puts("%");
X  puts("%   /LOG       Enables file logging.");
X  puts("%   /NOLOG     Disables file logging.");
X  puts("%   /LOGME     Enables keyboard input logging.");
X  puts("%   /NOLOGME   Disables keyboard input logging.");
X  puts("%");
X  puts("%   /QUIET     Prevents login messages from being displayed.");
X  puts("%   /NOQUIET   Allows login messages to be displayed.");
X  puts("%");
X  puts("%   /LOGIN     Enables automatic login.");
X  puts("%   /NOLOGIN   Prevents automatic login.");
X  puts("%");
X  puts("%   /DEF       Defines a macro.");
X  puts("%   /UNDEF     Undefines a macro.");
X  puts("%   /LISTDEF   Lists currently defined macros.");
X  puts("%   /LOADDEF   Reads macro definitions from a file.");
X  puts("%   /SAVEDEF   Saves macro definitions in a file.");
X  puts("%   /macro     Invokes a macro.");
X  puts("%");
X  puts("%   /HELP2     For more help.");
X}
X
Xhandle_help2_command(args)		/* Give user some help. */
X  char *args;
X{
X  puts("% Summary of commands:");
X  puts("%   /QUIT      Quits TinyTalk.");
X  puts("%   /INTR      Enables control-C.");
X  puts("%   /NOINTR    Disnables control-C.");
X  puts("%");
X  puts("%   /BEEP      Enables beeps for pages.");
X  puts("%   /NOBEEP    Disables beeps for pages.");
X  puts("%");
X  puts("%   /STTY      Reads system's keyboard setup.");
X  puts("%   /NOSTTY    Uses default keyboard setup.");
X  puts("%");
X  puts("%   /GAG       Prevents messages from a user from being displayed.");
X  puts("%              Also /NOGAG, /LISTGAG, /LOADGAG, and /SAVEGAG.");
X  puts("%");
X  puts("%   /HILITE    Hilites messages from a user.  The special arguments");
X  puts("%              PAGE and WHISPER enable hiliting for those.");
X  puts("%              Also /NOHILITE, /LISTHILITE, /LOADHILITE, and /SAVEHILITE.");
X  puts("%");
X}
X
Xhandle_listdef_command(args)
X  char *args;
X{
X  if (args[0] != '\0') {
X    if (equalstr(args, "FULL"))
X      list_all_macros(TRUE);
X    else
X      fprintf(stderr,"%% The only option to /listdef is 'full'.\n");
X  }
X  else
X    list_all_macros(FALSE);
X}
X
Xhandle_loaddef_command(args)
X  char *args;
X{
X  do_file_load("/DEF ", args, "~/tiny.macros");
X}
X
Xhandle_quit_command(args)
X  char *args;
X{
X  set_done();
X}
X
Xhandle_beep_command(args)
X  register char *args;
X{
X  if (args[0] == '\0')			/* No arguments, default to 3 beeps */
X    set_beep(3);
X  else {
X    if ((args[0] < '0') || (args[0] > '9')) /* Verify starts numeric. */
X      fprintf(stderr,"%% Invalid beep count %s.\n", args);
X    else
X      set_beep(atoi(args));		/* If argument, use it. */
X  }
X}
X
Xhandle_nobeep_command(args)
X  char *args;
X{
X  set_beep(0);
X}
X
Xhandle_intr_command(args)
X  char *args;
X{
X  allow_interrupts();
X}
X
Xhandle_nointr_command(args)
X  char *args;
X{
X  disallow_interrupts();
X}
X
Xhandle_stty_command(args)
X  char *args;
X{
X  use_stty();
X}
X
Xhandle_nostty_command(args)
X  char *args;
X{
X  no_use_stty();
X}
X
Xhandle_gag_command(args)
X  char *args;
X{
X  if (args[0] == '\0')
X    enable_gagging();
X  else
X    add_gag(args);
X}
X
Xhandle_nogag_command(args)
X  char *args;
X{
X  if (args[0] == '\0')
X    disable_gagging();
X  else
X    remove_gag(args);
X}
X
Xhandle_listgag_command(args)
X  char *args;
X{
X  list_gag();
X}
X
Xhandle_loadgag_command(args)
X  char *args;
X{
X  do_file_load("/GAG ", args, "~/tiny.gag");
X}
X
Xhandle_savegag_command(args)
X  char *args;
X{
X  save_gag(args);
X}
X
Xhandle_hilite_command(args)
X  register char *args;
X{
X  if (args[0] == '\0')
X    enable_hiliting();
X  else if (equalstr(args, "PAGE") || equalstr(args, "PAGES"))
X    enable_page_hiliting();
X  else if (equalstr(args, "WHISPER") || equalstr(args, "WHISPERS"))
X    enable_whisper_hiliting();
X  else if (equalstr(args, "NOPAGE") || equalstr(args, "NOPAGES"))
X    disable_page_hiliting();
X  else if (equalstr(args, "NOWHISPER") || equalstr(args, "NOWHISPERS"))
X    disable_whisper_hiliting();
X  else
X    add_hilite(args);
X}
X
Xhandle_nohilite_command(args)
X  register char *args;
X{
X  if (args[0] == '\0')
X    disable_hiliting();
X  else if (equalstr(args, "PAGE") || equalstr(args, "PAGES"))
X    disable_page_hiliting();
X  else if (equalstr(args, "WHISPER") || equalstr(args, "WHISPERS"))
X    disable_whisper_hiliting();
X  else
X    remove_hilite(args);
X}
X
Xhandle_listhilite_command(args)
X  char *args;
X{
X  list_hilite();
X}
X
Xhandle_loadhilite_command(args)
X  char *args;
X{
X  do_file_load("/HILITE ", args, "~/tiny.hilite");
X}
X
Xhandle_savehilite_command(args)
X  char *args;
X{
X  save_hilite(args);
X}
X
X  /* Generic routine to load commands of a specified type from a file. */
X
Xdo_file_load(cmd, args, default_name)
X  register char *cmd;
X  char *args, *default_name;
X{
X  register FILE *cmdfile;
X  int done;
X  string line;
X  char temp[20];			/* Big enough for any command. */
X  int length;
X
X  length = strlen(cmd);			/* Length of expected command. */
X
X  if (args[0] == '\0')			/* No filename, use default. */
X    strcpy(args, default_name);
X
X  expand_filename(args);
X
X  cmdfile = fopen(args, "r");
X  if (cmdfile == NULL)
X    fprintf(stderr,"%% Couldn't open file %s.\n", args);
X  else {
X    done = FALSE;
X
X    while (!done) {
X      if (fgets(line, MAXSTRLEN, cmdfile) == NULL)
X	done = TRUE;
X      else {
X	if (line[0] != '\0')		/* Get rid of newline. */
X	  line[strlen(line)-1] = '\0';
X
X	if ((line[0] == '\0') || (line[0] == ';')) /* Blank or comment. */
X	  continue;
X
X	strncpy(temp, line, length);	/* Length of command (incl. space). */
X	temp[length] = '\0';		/* Terminate after command. */
X	if (!equalstr(temp, cmd)) {
X	  fprintf(stderr,"%% Illegal line: %s.\n", line);
X	  done = TRUE;
X	}
X	else {
X	  handle_command(line,FALSE); /* Process this recursively. */
X	}
X      }
X    }
X
X    fclose(cmdfile);
X  }
X}
X
Xhandle_whisper_command(args)
X  char *args;
X{
X  disable_whisper_gagging();
X}
X
Xhandle_nowhisper_command(args)
X  char *args;
X{
X  enable_whisper_gagging();
X}
X
Xhandle_recall_command(args)
X  char *args;
X{
X  avoid_recall();			/* Don't recall this! */
X  do_keyboard_recall();			/* Recall last keyboard buffer. */
X}
X
Xhandle_listworlds_command(args)
X  char *args;
X{
X  register world_rec *p;
X
X  p = get_world_header();
X  while (p != NULL) {
X    printf("%% %s\n", p->world);
X    p = p->next;
X  }
X}
X
Xhandle_world_command(args)
X  char *args;
X{
X  char *place, ch;
X  register world_rec *where;
X
X  if (args[0] == '\0') {
X    where = get_default_world();
X    if (where == NULL) {
X      fprintf(stderr, "%% No default world is set.");
X      return;
X    }
X  }
X  else {
X    where = find_world(args);
X    if (where == NULL) {
X      fprintf(stderr, "%% The world %s is unknown.", args);
X      return;
X    }
X  }
X
X  if (connect_to(where))
X    magic_login();
X  else
X    fprintf(stderr,"%% Connection to world %s failed.\n", where->world);
X}
END_OF_FILE
if test 13833 -ne `wc -c <'tinytalk/command.c'`; then
    echo shar: \"'tinytalk/command.c'\" unpacked with wrong size!
fi
# end of 'tinytalk/command.c'
fi
if test -f 'tinytalk/fred.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tinytalk/fred.c'\"
else
echo shar: Extracting \"'tinytalk/fred.c'\" \(3325 characters\)
sed "s/^X//" >'tinytalk/fred.c' <<'END_OF_FILE'
X/************************************************************************/
X/* TinyTalk : Connect to a TinyMUD world.				*/
X/*									*/
X/*	Version 1.0 [ 1/24/90] : Initial implementation by ABR.		*/
X/*				 Contact rang@cs.wisc.edu for support.  */
X/*									*/
X/*		1.1 [ 2/ 2/90] : Added many new commands; reorganized   */
X/*				 some files.				*/
X/*									*/
X/*   This program connects to a TinyMUD world via the TELNET protocol.  */
X/* It provides the following features:					*/
X/*									*/
X/*   Portal recognition: Some TinyMUD systems have portals to other     */
X/*                       worlds.  TinyTalk deals with these correctly.  */
X/*									*/
X/*   Word wrap: If word wrap is desired, it may be enabled.		*/
X/*									*/
X/*   Command refresh: When TinyMUD prints a message, the command line   */
X/*		      typed so far is reprinted.			*/
X/*									*/
X/*   Macros: Simple macros may be defined.				*/
X/*									*/
X/*   Configuration file: Characters, parameters, and macros may be set  */
X/*			 automatically.					*/
X/*									*/
X/*   Page handling: Pages may trigger beeps.				*/
X/*									*/
X/*   Gags: Messages from certain characters or robots may be ignored.	*/
X/*									*/
X/************************************************************************/
X
X#include <stdio.h>
X#include "tl.h"
X
Xextern world_rec *get_default_world(), *find_world();
Xextern char *malloc();
X
Xworld_rec *boot_world();
X
Xmain(argc, argv)
X  int argc;
X  char *argv[];
X{
X  world_rec *first_world;
X
X  clear_quiet();			/* Initialize subsystems.	  */
X  init_logging();			/* Don't do keyboard yet, though. */
X  init_macros();
X  enable_auto_login();
X  enable_wrap(0);			/* Enable default wrapping. */
X  set_beep(3);				/* Set default beep mode. */
X  init_hiliting();
X  init_gagging();
X  preinit_keyboard();			/* Initialization before */
X					/* config file is read. */
X
X  read_configuration();
X  first_world = boot_world(argc, argv);
X
X  init_keyboard();
X  do_stuff(first_world);
X}
X
Xworld_rec *boot_world(argc, argv)
X  register int argc;
X  register char *argv[];
X{
X  register world_rec *temp;
X
X  if ((argc >= 2) && (!strcmp(argv[1], "-"))) { /* Option '-'. */
X    disable_auto_login();
X    --argc;
X    argv++;
X  }
X
X  if (argc == 1) {			/* Try default world */
X    temp = get_default_world();
X
X    if (temp == NULL)
X      die("%% You must specify a world; there is no default set.\n");
X    else				/* Have a default. */
X      return (temp);
X  }
X  else if (argc == 2) {			/* World specified. */
X    if (argv[1][0] == '-') {		/* Check for '-' option */
X      disable_auto_login();
X      argv[1]++;
X    }
X    temp = find_world(argv[1]);
X    if (temp == NULL)
X      die("%% The world %s is unknown.\n", argv[1]);
X    else
X      return (temp);
X  }
X  else if (argc == 3) {			/* Port and address specified. */
X    temp = (world_rec *) malloc(sizeof(world_rec)); /* Never reclaimed! */
X    temp->next = NULL;
X    strcpy(temp->world, "World");
X    *(temp->character) = '\0';
X    *(temp->pass) = '\0';
X    if (argv[1][0] == '-') {		/* Disable auto login; otherwise */
X      disable_auto_login();		/* we might use the default. */
X      argv[1]++;
X    }
X    strcpy(temp->address, argv[1]);
X    strcpy(temp->port, argv[2]);
X    return (temp);
X  }
X  else
X    die("Usage: %s [world]\n       %s address port\n", argv[0], argv[0]);
X
X  return (NULL);
X}
END_OF_FILE
if test 3325 -ne `wc -c <'tinytalk/fred.c'`; then
    echo shar: \"'tinytalk/fred.c'\" unpacked with wrong size!
fi
# end of 'tinytalk/fred.c'
fi
if test -f 'tinytalk/tinytalk.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tinytalk/tinytalk.doc'\"
else
echo shar: Extracting \"'tinytalk/tinytalk.doc'\" \(19225 characters\)
sed "s/^X//" >'tinytalk/tinytalk.doc' <<'END_OF_FILE'
X			   TinyTalk, V1.1.1
X			      Anton Rang
X			   ================
X
XWhat is TinyTalk?
X-----------------
X
X  TinyTalk is an interface to the TinyMUD system.  It replaces telnet,
Xand adds many new features.  Its features include:
X
X  * TinyTalk can wrap words at the end of a line.
X
X  * TinyTalk can automatically log into your characters.
X
X  * TinyTalk can record a TinyMUD session to a file.
X
X  * TinyTalk keeps your typing and TinyMUD output from being
X    intermingled.
X
X  * TinyTalk allows input lines to be up to 512 characters long.
X    This allows long descriptions to be entered.
X
X  * TinyTalk supports simple macros.
X
X  * TinyTalk supports "portals", special exits which connect between
X    the various TinyMUD systems.  There are also commands which allow
X    manually switching systems.
X
X  * TinyTalk can hilite pages and whispers, on terminals which support
X    boldface or inverse characters.
X
XWho wrote TinyTalk?  What is its status?
X----------------------------------------
X
X  TinyTalk was written entirely by myself.  I can be reached via
XE-mail, at "rang@cs.wisc.edu".  TinyTalk is semi-supported; bugs will
Xbe fixed, and new features may be incorporated into future versions.
XMail any comments or questions to me.
X
X  Stewart Clamen (aka "Stewy") came up with the idea for portals, and
Xadded support for them into the GNU Emacs-based client (tinymud.el).
XThe first free-standing program that I know of which implemented them
Xwas written by Russ Smith (aka "Nightfall").  They may be reached at
Xthe addresses "clamen@cs.cmu.edu" and "russ@uokmax.ecn.uoknor.edu".
X
X  Support for HP-UX was contributed by Andy Norman; support for System
XV was contributed by Kipp Hickman.  If you have problems with these,
Xlet me know; I may have erred in integrating them into the main
Xversion.
X
X  Thanks also go to my many beta testers, too numerous to name here.
XThey've been most helpful in finding bugs and suggesting new and
Xuseful features.  Thanks to all who have suggested new features as
Xwell.
X
X  TinyTalk is in the public domain.  Feel free to make improvements,
Xor take parts of the code for your own programs.  I ask only two
Xthings (these aren't legal obligations, just requests):
X
X    * If you make changes to TinyTalk, change the version number.
X      Don't increment it (i.e. to 1.2 or 2.0); add something to the
X      end of the current version number.  For instance, you could
X      use your initials: TinyTalk 1.1/abr-1.  This way, no two
X      versions of TinyTalk are likely to have the same version number.
X
X    * If you distribute modified versions of TinyTalk, please leave a
X      pointer to derby.cs.wisc.edu (128.105.2.162) where the original
X      code may be FTPed from.
X
X  If you have a minor improvement in mind, it may be best just to send
Xme a mail message.  I can incorporate it into the next version.
X
XInstalling TinyTalk.
X--------------------
X
X  This is described in the separate README file which you should have
Xreceived with this file.  If you have not received it, you can FTP a
Xcopy from derby.cs.wisc.edu (128.105.2.162).  It is in the directory
X~ftp/pub/tinytalk.
X
XStarting Tinytalk.
X------------------
X
X  Before using TinyTalk for the first time, you may want to create a
Xconfiguration file (described below).  TinyTalk will run without one,
Xbut automatic logins and world recognition will not be available.  If
Xyou do not have a configuration file, a host name and port number must
Xbe specified, as with 'telnet'.  Configuration files are described in
Xa later section.
X
X  The simplest way to invoke TinyTalk is simply by typing its name,
Xwithout any arguments.  If a configuration file exists, this will read
Xit and connect to the first world in the file.  To connect to that
Xworld without logging in, the single argument '-' should be given.
X
X	tinytalk	Connects to the default world and attempts login.
X	tinytalk -	Connects to the default world without logging in.
X
X  To connect to an alternate world which is in the configuration file,
Xthe name of that world may be given as an argument.  A leading '-'
Xindicates that auto-login should be disabled.
X
X	tinytalk TinyHELL	Connects to the world TinyHELL.
X	tinytalk -TinyHELL	Connnects to TinyHELL without logging in.
X
X  To use TinyTalk without a configuration file, or to connect to a
Xworld which is not in the configuration file, the host name (or
XInternet address) and port number must be given, as with 'telnet'.  If
Xa default character exists in the configuration file, auto-login will
Xbe attempted; a leading '-' on the host suppresses this.
X
X	tinytalk 192.35.96.111 6250		Connects to TinyHELL.
X	tinytalk -uokmax.ecn.uoknor.edu 6250	Connects to TinyHELL, no login.
X
XUsing TinyTalk.
X---------------
X
X  TinyTalk works almost the same as a regular telnet interface would.
XOutput from TinyMUD is displayed on the screen.  To send a line to
XTinyMUD, just type the line and press return.  The most noticeable
Xdifference is that the line you are typing will usually not be mixed
Xin with the output.  (The exception is when an input line wraps
Xaround, in which case any entire lines typed so far will remain on the
Xscreen, above output from TinyMUD.)
X
X  Commands may be given to TinyTalk by entering a line which begins
Xwith a slash (/).  To send a line which begins with a slash to
XTinyMUD, you must start the line with two slashes.  (For instance,
Xtyping '//house' would send the line '/house' to TinyMUD.  Typing only
X'/house' would cause TinyTalk to look for a 'house' command.)
X
X  When you walk through a portal to another TinyMUD, TinyTalk will try
Xto automatically reconnect you to the new system.  If the world is
Xdefined in your configuration file (and auto-login has not been
Xdisabled), it will automatically connect you to your character there.
X
X  The backspace and delete keys function as usual; in addition,
Xcontrol-U or control-X will erase the entire input line.  Control-R
Xwill refresh the current input (which may span multiple lines).
XControl-W will erase the last word typed.  (Note: all of these
Xcharacters may be changed, using /stty mode.)
X
X  Control-C (or the interrupt character) will exit TinyTalk (unless
Xthe /nointr command is used); it's recommended that the standard
XTinyMUD command QUIT be used instead, though.  On systems which
Xsupport job control, control-Z (or whichever character has been set as
Xthe suspend character) will pause TinyTalk and return you to the
Xshell.  When you resume TinyTalk after it has been suspended, any
Xoutput from the server which has been received will be printed.
X
XCommands.
X---------
X
X  There are four classes of TinyTalk commands: general, logging,
Xmacro, and output control commands.  The general commands are:
X
X  /quit		    Exits from TinyTalk.
X
X  /help		    Prints a short summary of TinyTalk commands.
X  /help2	    Prints another short summary.
X
X  /wrap [column]    Turns on word wrap mode, optionally setting the
X		    right margin.  Word wrap mode is enabled by
X		    default, at the terminal's normal right margin
X		    (or column 80 if this is not known).
X
X  /nowrap	    Turns off word wrap mode.  The current column is
X		    remembered, and a later /wrap command without an
X		    argument will default to that column.
X
X  /login	    Enables automatic logins.  These are enabled by
X		    default.
X
X  /nologin	    Disables automatic logins.  If you dislike the
X		    automatic login feature, you can place this
X		    command in your configuration file.  Another use
X		    for it is when going through a portal to a world
X		    in which you don't have a character (or wish to
X		    connect to a character which isn't your default).
X
X  /quiet	    Turns on "quiet" mode.  In quiet mode, automatic
X		    logins don't print the prompts from the server
X		    (for instance, "Welcome To TinyMUD"..."Use WHO").
X		    If you like this option, you probably want to put
X		    this command in your configuration file.  This has
X		    no effect if automatic logins are disabled.
X
X  /noquiet	    Turns off quiet mode.  Automatic logins will show
X		    the entire server message.
X
X  /intr		    Enables interrupt mode; ^C will exit TinyTalk.
X		    This is enabled by default.
X
X  /nointr	    Disables interrupt mode; ^C will be ignored.
X
X  /stty		    Causes TinyTalk to use the current terminal
X		    configuration for line editing characters.
X
X  /nostty	    Causes TinyTalk to use its default line editing
X		    characters.  This is the default.
X
X  /recall	    Recalls the last (non-empty) line typed.  This is a
X		    very limited form of command recall, useful mainly
X		    when working with an unreliable connection.
X
X  /listworlds	    Lists the worlds defined in your configuration file.
X
X  /world [name]	    Switches the connection to an alternate world.  If
X		    no world is given, connects to the default world.
X		    (Note that this breaks the connection with the old
X		    world; TinyTalk only maintains one connection at a
X		    time.)
X
XLogging commands control whether a TinyTalk session is saved into a
Xfile.  If you are using a terminal emulation program which does
Xlogging, you may not need these commands.
X
X  /log [filename]   Enables logging.  All output from the server will
X		    be logged into the specified file.  If no file has
X		    been specified, "~/tiny.log" will be used.  (Once a
X		    filename has been set, future /log commands during
X		    the same session will remember that filename.)
X
X  /nolog	    Disables logging.  The file is closed, and no
X		    output will be sent to it.  This is the default.
X
X  /logme	    Enables input logging.  Everything typed at the
X		    keyboard (including commands and TinyMUD input)
X		    will be logged, if logging is enabled.
X
X  /nologme	    Disables input logging.  Only output from the
X		    server will be logged.  This is the default.
X
XMacro commands allow macros to be defined.  Macros are discussed in
Xmore detail in the next section.
X
X  /def name = body  Defines the macro 'name'.  'Name' must not be a
X		    current macro.  Names are not case-sensitive, and
X		    any names which are the same as a TinyTalk command
X		    name will not be usable.
X
X  /undef name	    Undefines the macro 'name', allowing it to be
X		    redefined.
X
X  /listdef [full]   Lists the current macro definitions.  By default,
X		    this only lists their names.  If the keyword
X		    'full' is given, both names and bodies will be
X		    listed.
X
X  /savedef [file]   Saves all current macro definitions into a file.
X		    If no filename is given, "tiny.macros" will be
X		    used.  Warning: this will overwrite any existing
X		    file by the name; use it with caution.
X
X  /loaddef [file]   Loads macro definitions from a file.  The file
X		    may have been created with /savedef, or may be
X		    simply a list of /def commands (possibly with
X		    comments, lines starting a semicolon, interspersed).
X
XOutput control commands.
X------------------------
X
X  These commands control special processing of messages from TinyMUD.
X
X  /beep [count]	    When /beep is enabled, page messages ("You sense that")
X		    are signaled with one more beeps.  The default is 3.
X
X  /nobeep	    This disables /beep; pages are not signaled.
X
X  /hilite [mode]    This enables hiliting of some output message.  Mode
X		    may be 'page', to hilite pages; 'whisper', to hilite
X		    whispers to you; or the name of a person, in which
X		    case all their actions will be hilited.  If no mode
X		    is specified, person-hiliting is enabled (though
X		    only previously added people will be hilited).
X
X  /nohilite [mode]  This reverses /hilite.  It can be used to disable
X		    hiliting of pages or whispers, or to remove a person
X		    from the list of hilited people.  If no mode is
X		    specified, person-hiliting is disabled; however,
X		    the list of hilited people remains intact.
X
X  /listhilite	    Lists persons being hilited, and indicates whether
X		    page and whisper hiliting is enabled.
X
X  /loadhilite [f]   Retrieves a list of characters to hilite from a file.
X		    The default name is '~/tiny.hilite'.
X
X  /savehilite [f]   Saves a list of characters to hilite in a file.  The
X		    default name is '~/tiny.hilite'.
X
X  /gag [person]	    This command suppresses output from a character.
X		    It may be useful for ignoring robots, for example.
X		    Arrival, departure, and kill messages are never
X		    suppressed.  With no arguments, gagging is enabled.
X
X  /nogag [person]   This command removes a character from the "gag list".
X		    With no arguments, gagging is disabled, but the list
X		    of gagged characters is retained.
X
X  /loadgag [f]      Retrieves a list of characters to "gag" from a file.
X		    The default name is '~/tiny.gag'.
X
X  /savegag [f]      Saves a list of characters to "gag" in a file.  The
X		    default name is '~/tiny.gag'.
X
X  /whisper	    Lets whispers be shown, on systems which support
X		    "noisy whisper".
X
X  /nowhisper	    Prevents whispers to others from being shown, in
X		    effect simulating "quiet whisper".  This is not
X		    infallible, and may prevent some messages which
X		    are not actually true whispers from being shown,
X		    if they appear to be whispers.
X
XMacros.
X-------
X
X  TinyTalk macros, while simple, are powerful.  Macros can range in
Xcomplexity from simply moving between rooms to creating a private note
Xto someone.
X
X  The simplest type of macro has no arguments.  It is defined with the
X/def command.  This macro can be invoked simply by using its name as a
Xcommand.  For instance, entering the line
X
X	/def pizza = "I like pizza!
X
Xwill define a macro named 'pizza', which will send the string ' "I like
Xpizza! ' to TinyMUD when it is invoked.  Typing
X
X	/pizza
X
Xwill cause your character to say "I like pizza!", just as though you
Xhad typed ' "I like pizza! ' yourself.
X
X  The special sequences %\ and %; will cause an end-of-line to be
Xinserted within the macro, just as though you had typed a return.  If
Xyou changed your mind and wanted your character to say "I like pizza!"
Xand then smile, you could remove the current pizza macro and define a
Xnew one:
X
X	/undef pizza
X	/def pizza = "I like pizza!%;:smiles.
X
X  Now, typing the command '/pizza' will result in TinyMUD receiving
Xthe following two commands.
X
X	"I like pizza!
X	:smiles.
X
X  If you want to use the percent sign (%) in a macro and have it sent
Xto TinyMUD (for instance, "I like pizza 100% better than spinach"),
Xyou must use two percent signs.  Only one will be sent through.
X
X	/def better = "I like pizza 100%% better than spinach.
X
X  Macros may take "arguments"; that is, they may do different things
Xdepending on exactly what command is used to start them.  For
Xinstance, you may like pizza better than lots of foods, but not want
Xto define a macro for every food.  You could use the following macro.
X
X	/def better = "I like pizza 100%% better than %1.
X
X  The special sequence '%1' will cause the first word after '/better'
Xto be inserted there.  For instance, typing:
X
X	/better artichokes
X
Xwill cause TinyMUD to receive
X
X	"I like pizza 100% better than artichokes.
X
X  Up to four arguments can be used; they are numbered one through
Xfour.  A special case is %*, which causes the entire command line
Xfollowing the name of the macro to be inserted.  For instance, if you
Xwanted to always start your character's description with the same
Xstring, you could define a macro:
X
X	/def pickle = @desc me = You see a pickle. %*
X
XIf you then typed
X
X	/pickle You decide that it's probably dill.
X
XTinyMUD would receive
X
X	@desc me = You see a pickle. You decide that it's probably dill.
X
X  Arguments cannot have spaces in them, except for the special case of
X%*.  This restriction may be changed in a later version of TinyTalk.
X
XThe configuration file.
X-----------------------
X
X  The configuration file is used to define worlds, and to set TinyTalk
Xoptions when it starts (for instance, to define some initial macros).
XIf the environment variable TINYTALK is defined, TinyTalk will look at
Xthe file named there for its configuration; otherwise, it reads a
Xdefault configuration file named '.tinytalk' in the user's home
Xdirectory (~/.tinytalk).
X
X  WARNING: You should make sure that your ~/.tinytalk file is
Xprotected against access by other users, by using the chmod command.
XIf you don't do this, other users can find out your character names
Xand passwords.
X
X  A configuration file has two sections.  The first defines the worlds
X(and characters) which TinyTalk knows about.  The second section
Xconsists of TinyTalk commands, which will be executed when TinyTalk
Xstarts up.  The sections are separated by a blank line.
X
X  The first line of the world definition section is used as a default
Xworld (if TinyTalk is invoked with no arguments).  This should be the
Xworld you enter the most, usually.
X
X  Each line of the world definition section contains five sections
X(except for the default--see below).  This defines a world, a
Xcharacter, and an address for the world.  An example would be:
X
X	TinyMUD MyCharacter MyPassword daisy.learning.cs.cs.cmu 4201
X
X  This line (which, if used in a configuration file, should not have
Xany leading spaces) would define the world TinyMUD.  It would use the
Xpassword MyPassword to automatically log into MyCharacter.  It would
Xuse the hostname daisy.learning.cs.cmu.edu, and port 4201.
X
X  A line with the world name "default" (and no host address or port)
Xis special.  It defines a character and password to be used for all
Xworlds which are not otherwise defined in the configuration file.  If
Xyou define all the worlds you normally visit in the configuration
Xfile, this is not very useful; however, it may allow new worlds to be
Xaccessed through portals more easily.
X
X  After the world definition section, any TinyTalk commands may be
Xentered.  These may include setting quiet modes, a wrap column, or
Xdefining macros.
X
X  An example configuration file, with comments, follows.  It really
Xisn't as complicated as the above makes it sound!
X
X--------------------
X
X;
X; This is an example TinyTalk configuration file.  It can be copied to
X; ~/.tinytalk and modified to suit your needs and wishes.
X;
XTinyMUD YourName YourPass daisy.learning.cs.cmu.edu 4201
XTinyHELL YourName YourPass 192.35.96.111 6250
X
X;
X; The preceding blank line terminates the list of worlds.
X; Any legal commands can go in this section.
X;
X/quiet
X/log
X/hilite page
X/hilite whisper
X;
X; Here are a few example macros.  (These lines are long, because
X; macros must be defined on a single line.)
X;
X; Create a note and lock it to somebody.  Invoked as /makenote (whoever).
X;
X/def makenote = @create Note for %1%\@lock Note for %1 = *%1%\@osucc Note for %1 = reads the note%\@fail Note for %1 = You can't read the note.%\@ofail Note for %1 = tries to read a note, but can't.%\@desc Note for %1 = A private note for %1.
X;
X; Take an existing note and lock it to somebody. Invoked as /usenote (whoever).
X; Assumes you are carrying an object named "Note for (whoever)".
X;
X/def usenote = @lock Note for %1 = *%1%\@osucc Note for %1 = reads the note%\@fail Note for %1 = You can't read the note.%\@ofail Note for %1 = tries to read a note, but can't.%\@desc Note for %1 = A private note for %1.
X;
X; Macros to move around are useful.  This one is specific to my configuration;
X; it moves from my home to the rec room.
X;
X/def rec = out%\s%\s%\s%\rec%\
END_OF_FILE
if test 19225 -ne `wc -c <'tinytalk/tinytalk.doc'`; then
    echo shar: \"'tinytalk/tinytalk.doc'\" unpacked with wrong size!
fi
# end of 'tinytalk/tinytalk.doc'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0