Subject: Caution, server hacks ahead! <longish>

From: James Powell <[email-masked]>
Date: Tue, 2 Mar 1993 21:44:31 -0800

Hey all. This sounds like a good time to report on some work in progress.
Aardvark-V 'n I have been plugging away on a new look for MOO, and one of our
current projects is support for Tektronix 4014 emulation. It's a nice little
graphics standard that has been around forever, and tons of apps have been
written for it, so it's quite tried and true and there are free emulators
available for most platforms. The original Tek was, I believe, a smart
terminal endowed with a vector display, so Tek graphics are entirely vector
based (read no bitmaps). We're developing the driver simply as an object,
pure evasion of the great "where to put the TERMCAP entries?" question. All
in all, it's pretty nifty and it works. We hope to release something soon,
but in the mean time, here's how we've approached the 8-bit ASCII question:

The user currently has two options:

1) $tek can send non-printing ASCII characters as an escape character (we're
   using tilde) followed by the hex code of the character in question. Use
   of this requires a client that will catch the escapes and translate them.
   I've built a bit of plumbing that allows you to telnet to some port at
   some local site, and then be automagically connected to yet another port
   at yet another site, and which does this translation for you. Something
   like this eliminates the need for a customized client and for server
   modification. It could even work for Lambda. It does presently require
   an entry in /etc/inetd.conf.

2) $tek can send the ascii codes directly, via the builtin ascii() function
   which I hacked into 1.7.0 thusly:

   Edit the file "list.c".
   Proceed to line 543, and above the lines that read:

static package
bf_tostr(Var arglist, Byte next, void *vdata, Objid progr)

   Insert the following text:

static package bf_ascii(Var arglist, Byte next, void *vdata, Objid progr)
{
  Var r;
  r.type = TYPE_STR;
  r.v.str =ascii_list2str(arglist.v.list); 
  free_var(arglist);
  return make_var_pack(r);
}

   Then proceed to line 233, and above the following lines:

Var
strrangeset(Var base, int from, int to, Var value)

   [isn't that a great function name?] Insert the following text:

char *
ascii_list2str(Var *args)
{
    static Stream      *str = 0;
    int			i;
    char buff[20];
    
    if (!str)
        str = new_stream(100);
   
    for (i = 1; i <= args[0].v.num; i++) {
	switch (args[i].type) {
	  case TYPE_NUM:
		  buff[0]=(char)args[i].v.num;
		  buff[1] = '\0';
		  stream_printf(str, "%s", buff);
		  break;
	  case TYPE_OBJ:
		  stream_printf(str, "#%d", args[i].v.obj);
		  break;
	  case TYPE_STR:
		  stream_add_string(str, args[i].v.str);
		  break;
	  case TYPE_ERR:
		  stream_add_string(str, unparse_error(args[i].v.err));
		  break;
	  case TYPE_LIST:
		  stream_add_string(str, "{list}");
		  break;
	  default:
		  panic("LIST2STR: Impossible var type.\n");
	}
    }
    return str_dup(reset_stream(str));
}

   And finally, proceed to line 794 (note that it is 794 only after you make
   the above additions) and between these two lines:

(void) register_function("tostr", 0, -1, bf_tostr);
. o O ( <- here )
setup_regex();

   Add the following line:

(void) register_function("ascii", 0, -1, bf_ascii);

   Save your changes to "list.c".
   Type "make", and install your nifty new, ascii()'ed server.

While there are no guarantees, expressed or implied, regarding these changes
and any possible side effects they might have on your db, your server (version
1.7.0 or otherwise), and the sanity and sactity of your players and their
terminals, and regarding everything else, too (gee, I'm in the wrong profess-
ion!), I do hope this code is of use to someone.
  -Minstrel aka "Dr. Strrange"-