$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On  6-MAR-1993 00:22:55.59   By user HEB3212 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$!+ THIS PACKAGE DISTRIBUTED IN 6 PARTS, TO KEEP EACH PART
$!  BELOW 30 BLOCKS
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. DINK.C;1
$!       2. DINK.DOC;1
$!       3. DINK.H;1
$!       4. DINK.INIT;1
$!       5. DINK.OPT;1
$!       6. DINK_CMD.C;1
$!       7. DINK_CMD.H;1
$!       8. DINK_FILT.C;1
$!       9. DINK_FUNC.C;1
$!      10. DINK_GAG.C;1
$!      11. DINK_HILITE.C;1
$!      12. DINK_MACRO.C;1
$!      13. DINK_MATCH.C;2
$!      14. DINK_MULTINET.OPT;1
$!      15. DINK_NET.C;1
$!      16. DINK_RUN.C;1
$!      17. DINK_WOLLONGONG.OPT;1
$!      18. MAKEDINK.COM;1
$!      19. README.;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X/*
X  DINK 1.0 by David Konerding 7/91
X  DINK 2.0 by Martin Hebrank 3/93
X  This code is released into the public domain.  I do not guarantee
X  reliability.  If you have ideas, questions, comments, bugs, email me
X `20
X  Martin Hebrank
X  ba344@cleveland.freenet.edu
X
X `20
X  */
X
X#include <types.h>
X#include <netdb.h>
X#include <in.h>
X#include <iodef.h>
X#include <socket.h>
X#include "dink.h"
X
Xmain(argc,argv)
X     int argc;
X     char *argv`5B`5D;
X    `20
X`7B
X  int flags;
X  long sts;
X  unsigned short tmud_port;
X  char *host_name;
X  struct dsc$descriptor terminal_desc;
X  struct world *tmp;
X `20
X  supress_next_cr = 0;
X  init_filters();
X  move_to(1,1);
X  out_y=out_x=1;
X  printf(ERASE_EOS);
X  printf(SCROLLING_REGION);
X
X  run_file("dink.init");
X
X  current_world=0;
X  switch (argc) `7B
X  case 1 :`20
X    if (world_list==NULL) add_handler("fubar nauer.csuohio.edu 7719");
X    current_world=world_list;
X    current_world->channel=connect_world(current_world,0);
X    if (current_world->channel == NULL)
X      `7B
X`09print_buffer("\nFailed to connect to ",1);
X`09print_buffer(current_world->name,1);
X        printf(FULL_SCROLLING_REGION);
X        move_to(20,1);
X        printf(ERASE_EOS);
X`09exit(1);
X      `7D
X    break;
X   `20
X  case 2 :`20
X    for(tmp=world_list;;tmp=tmp->fwd)
X      `7B
X`09if (!strcmp(tmp->name,argv`5B1`5D))
X`09  `7B
X`09    current_world=tmp;
X`09    current_world->channel=connect_world(tmp,0);
X`09    if (current_world->channel == NULL)
X`09      `7B
X`09`09print_buffer("\nFailed to connect to ",1);
X`09`09print_buffer(current_world->name,1);
X                printf(FULL_SCROLLING_REGION);
X                move_to(20,1);
X                printf(ERASE_EOS);
X`09`09exit(1);
X`09      `7D
X`09    break;
X`09  `7D
X`09if (tmp->fwd==world_list) break;
X      `7D
X    if (current_world==0)
X      `7B
X`09print_buffer("\nCould not connect to world ",1);
X`09print_buffer(argv`5B1`5D);
X        printf(FULL_SCROLLING_REGION);
X        move_to(20,1);
X        printf(ERASE_EOS);
X`09exit(1);
X      `7D
X    break;
X  default:`20
X    printf("Usage: dink <startup world>\nor\ndink\n");
X    printf(FULL_SCROLLING_REGION);
X    move_to(20,1);
X    printf(ERASE_EOS);
X    exit(1);
X  `7D
X `20
X  /* Set up for terminal I/O */
X `20
X  terminal_desc.dsc$w_length = strlen("tt:");
X  terminal_desc.dsc$a_pointer = "tt:";
X  terminal_desc.dsc$b_class = DSC$K_CLASS_S;`09/* String desc class */
X  terminal_desc.dsc$b_dtype = DSC$K_DTYPE_T;`09/* Ascii string type */
X `20
X  sts = sys$assign(&terminal_desc,&terminal_chan,0,0);
X `20
X  dink();
X `20
X`7D
$ CALL UNPACK DINK.C;1 1633376065
$ create 'f'
XDINK 2.0  mostly by: Martin Hebrank (ba344@cleveland.freenet.edu)`20
X  much of the version 1.0 code by:
X   David Konerding (DKONERDING@EAGLE.WESLEYAN.EDU and rafael@asylum)
X
X
XDINK is the successor to TINT.  It adds a few features to TINT2.2 but is
Xsmaller.  TINT was written by Andrew Molitor and later hacked by me.
XDINK is a client for use with any MU* client that runs under VMS with the
XMultiNet or Wollongong netwar packages.
X
XTo compile DINK, use the file MAKEDINK.COM.  Instructions on how to compile
Xusing either MultiNet or Wollongong, read MAKEDINK.COM before executing it.`
V20
XA makefile has been included for people who have MMS or MAKE and want to cha
Vnge
Xthe source code.  Read MAKEFILE. before using it to compile.
X
XTo run DINK set it up in it's own directory and set up a few symbols. One
Xwhich changes to that directory, and one that executes it. For information
Xon setting up symbols read the online helps.`20
X
XDINK runs a file called DINK.INIT which must reside in your current`20
Xdirectory (this is the reason why I tell you to change to you DINK`20
Xdirectory, it makes life easier.).
X
X`09DINK.INIT should contain the world definitions for as many worlds you
Xwish.  It can also contain gags, triggers,hilites-- any command you could
Xnormally type while in DINK. And now it can be used to send strings into
Xthe worlds too, because it just uses the RUN command that has been`20
Ximplemented in version 2.0.
X
X`09To initiate a DINK client session, invoke DINK from the DCL command
Xline by typing DINK and following it with an optional argument-- the world t
Vo
Xwhich you wish to connect.  The world *must* be defined in you DINK.INIT fil
Ve
Xor DINK will not run, unless you do not invoke DINK with an argument, in whi
Vch
Xcase it will connect to FUBARMush.
X
X`09If DINK manages to connect to the chosen world, the world's connection
Xinformation should appear on the screen.  If you've set up the proper trigge
Vrs,
XDINK will automatically connect for you.  If not, you can simply type the
Xproper connection string and you're ready to go!
X
X`09DINK's interface is called "visual" which means that the screen is
Xbroken into two windows.  The top window, 18 lines long, holds all the text
Xcoming from the MUD.  The bottom windows holds what you've typed so far.
XIn between the 2 windows is the 'status line' which seperates the windows
Xand shows your current world (implemented in version 2.0).
XTo finish off a line you've typed, hit the RETURN or ENTER key.  The
XCONTROL-U key will flush everything you've typed so far so you can start ove
Vr.`20
XThe backspace key will erase the last character you've typed.  `5EN and `5EP
V are
Xcommand history-- hitting `5EN repeatedly will allow you to go back and repe
Vat
Xsomething you've already typed, and `5EP will scroll forward within that buf
Vfer.
XTry it, it's neat!
X
X`09When you end a line by hitting RETURN or ENTER the line is scanned
Xfor macro substitutions (created with the /macro command) and register`20
Xsubstitions (created with the /reg command). It is possible for a macro to
Xuse a register in it, and for a register to use a macro. BE CAREFUL with`20
Xthis though, it is possible to get into an infinite loop by doing this!!
XIt will then replace any '`7C' with a carriage return. After this it will`20
Xeither interpret the line as a command (if the first character in the
Xline is a /) or send it to the MUD just like TELNET.
X
X`09The commands that DINK allows currently are:
X
X/gag regexp  <-- gags any incoming text matching the regexp
X/hilite regexp  <-- hilies any incoming text matching the regexp
X/ungag regexp  <-- ungags any existing regexp that matches the argument
X/unhilite regexp  <-- unhilites any existing regexp that matches the argumen
Vt
X/wait time text  <-- waits time seconds to send text (or do command)
X/macro name=text  <-- creates a macro of name that contains text
X/macrolist  <-- lists all macros currently defined (v2.0)
X/flag first letter of flag  <-- boolean(!) NOTs a flag
X/spawn  <-- spawns a subprocess
X/att  <-- attaches to parent process
X/pipe "prefix" filename  <-- pipes filename line by line to the MUD
X     `09optionally with "prefix" sent at the beginning of each line
X/log filename  <-- logs to filename.  If just /log, turns logging off
X/addworld worldname host port  <-- adds worldname (of host and port) to worl
Vd
X`09list
X/world worldname  <-- switches to worldname
X/listworld  <-- lists all the worlds in your world list. (v2.0)
X/trigger regexp=text  <-- any incoming text matching the regexp will send te
Vxt
X`09to MUD (or do command)
X/copy sourceregister targetregister  <-- copies contents of source register
X`09into target register
X/reg register=text  <-- copies text into named register
X/run filename  <-- runs filename as if you type the commands, also sends`20
X    `09strings straight to the world (a semicolon ; as the first character
X `09of the line uses that line as a comment and skips it.) (v2.0)
X
X`09Additional Command Help:
X
X/gag, /hilite, and /trigger regexps
X
X`09DINK's regexps are borrowed from Greg Hudson's TinyFugue package and
Xwere mostly written by he and Leo Plotkin.  They aren't really regexps, but
V do
Xemulate the *, ?, and `5Bstring of matching characters`5D features of regexp
Vs.
X
XQuotes in the following examples delimit the regexps and are not actually pa
Vrt
Xof the regexps.
X
X"*foo*" matches:
Xrafael says, "foo"
Xrafael foo
XRandom says, "rafael, you are a foo".
X
X"foo*" matches:
Xfoo says, "nef!"
Xbut NOT:
Xnef says, "foo!"
X
X"*foo" matches:
Xnef emotes foo
Xbut NOT:
Xnef says, "foo!"
Xfoo emotes "nef!"
X
X"foo?bar" matches:
Xfoobar
Xfooabar
Xfoobbar
X
X"`5BfF`5Doobar*" matches:
Xfoobar says, "nef!"
XFoobar says, "nef!"
X
XGet the idea?
X
X/gag *foo*  will gag everything incoming that has "foo" in it, anywhere--
Xbeginning, end, middle.
X
XText arguments:
X---------------
X
XSeveral commands-- /trigger, /wait, /reg, /macro have arguments which are
Xsimply text.
XIn all for cases, that text will be substituted into the keyboard buffer whe
Vn
Xnecessary.
X
X`09For example, if you have
X/trigger *foo*=say nef!
X
XEvery time "foo" is sent to you by the MUD, the client will send "say nef!"
V to
Xthe MUD.  This will happen even if you're in the middle of typing a line.
X
X`09If you have
X/wait 5 say nef!
X
XFive seconds later, "say nef!" will be sent to the MUD, even if you're in th
Ve
Xmiddle of typing a line.
X
X/reg register=text
Xwill place the text into the register.  You may substitute registers into yo
Vur
Xoutgoing buffer in a certain way explained later.
X
XMultiple lines output:
X----------------------
X
X`09The `7C (unix pipe) character acts as a command seperater. When it
Xis found in the input string it is replaced by a enter character unless it
Xis immediately preceded by a backslash (\). So to enter 2 commands on one`20
Xline type:
X
XWHO`7Clook
X
Xbut to include the `7C character in a macro or register definition it must b
Ve
Xpreceded by the backslash, like this:
X
X/macro foo=say foo\`7Csay bar
X
Xthis would send say foo and then say bar to the world when you type \foo.`20
XIf the backslash hadn't been included the macro definition would be "say`20
Xfoo" and it would have sent "say bar" to the world immediately.
X
X`09So, if you set up a trigger to watch for "*foo*" and you want DINK
Xto send "say nef" and then "say bar" when it the trigger is activated, do
Xthe following:
X
X/trigger *foo*=say nef\`7Csay bar
X
X`09You may use commands, too:
X
X/trigger *has arrived.=/copy x a\`7C/wait 5 say hello, \`5Ea!
X*should* greet a person five seconds after they enter a room.  This will bec
Vome
Xmore obvious later when you learn about the copy command and extraction
Xsubstitution.
X
XNOTE: these examples probably won't work.  DK
XNOTE: they should now. MH
X
XMacros:
X-------
X
X`09Create a macro by setting a name to equal an equivalence:
X/macro name=equivalence
X
X`09Every time you type a line into DINK with \name in the typed line, it
Xwill be replaced by the equivalence.  Macros work both at the start of the l
Vine
Xand in the middle.  You cannot feed arguments to macros with DINK1.0.
X
X/macro foo=say nef!
X\foo
X
XThe above will send "say nef!" to the mud every time you type "\foo" into DI
VNK.
XIf you type:
X
Xsay \foo
X
XDINK will send "say say nef!" to the MUD.
X
XFlags:
X------
X
XTwo flags currently exist within DINK, bamf and result.
X
+-+-+-+-+-+-+-+-  END  OF PART 1 +-+-+-+-+-+-+-+-
-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
XThey can be changed from on to off and back again by typing
X/flag flagname's first letter
X
X/flag B
Xor
X/flag b
Xwill turn flag bamf from on to off or off to on
X/flag BR
Xwill turn flag bamf from on to off or off to on and flag result from off to
V on
Xor on to off.
X
XWhen bamf is on, DINK will automatically reconnect to a new MUD when it
Xreceives the standard UnterNet reconnect string.  If bamf is off, it will no
Vt
Xdo so.
X
XWhen result is on, all command results will be printed, hilit, on your scree
Vn.`20
XIf result is off they will not be printed.
X
XProcess Handling:
X-----------------
X
X/spawn will spawn a subprocess if possible and /att will attach to a parent
Xprocess if possible.
X
XPiping and Logging:
X-------------------
X
XTo pipe a file to a MUD, type
X/pipe "prefix" filename
X
X"prefix" is optional.  If it is used, each line of file filename will be
Xprefixed with "prefix" and sent to MUD.  Otherwise, each line will be sent.
X
Xto run commands in a file, type
X/run filename
X
XThis will run all commands in filename as if you typed them at the
Xkeyboard. It will also send non-commands to the world. This is`20
Xpotentially very useful when used in conjuction with waits or triggers.
X
XTo log to a file all MUD text, type
X/log filename
X
XTo turn logging off, type
X/log
X
XWorlds:
X-------
X
XDINK supports multiple worlds.  DINK holds a list of "worlds" in memory and
Xallows you to switch from world to world by typing
X/world worldname
X
XTo add a world to DINK, type
X/addworld worldname host port
X
XTo list which worlds are in your world list, type
X/listworld
X
XIn my DINK.INIT, I have:
X
X/addworld asylum littlewood.math.okstate.edu 6250
X/addworld evil fido.econ.arizona.edu 4201
X
XI invoke DINK with
XDINK asylum
X
Xand am automatically connected to world asylum.  I can switch to world evil
V by
Xtyping
X/world evil
X
XRegisters:
X----------
X
XYou may substitute certain things into macros, triggers, and waits.
X
XThere are 26 registers, each accessed by following a carrot (`5E) with a let
Vter
Xof the alphabet to specify a register.
X
XIn order to use registers in a command you must precede it with a`20
Xbackslash (\) in the command definition, like in the next example.
X
XRegister X always holds the last name the MUD has sent to you, so
X/trigger * says, "rafael is a jerk"=kill \`5Ex=100
X
Xwill kill whoever says you're a jerk.
X
XYou can set a register equal to something by typing:
X/reg register=text
X
XSo
X/reg A=foobar!
X/macro foo=say `5Ea
X\foo
X
Xwill send
Xsay foobar!
Xto the MUD.
X
XYou can copy one register's contents to another's by typing
X/copy sourceregister targetregister
X
Xala:
X/copy x a
X
XThis is useful when you've got a trigger which needs to hold the name of the
Xperson it's trigger by for a while--
X
Xif you did
X/trigger *says, "rafael's a jerk"=say I'll get one you day\`7C/wait 10=kill
X\`5Ex=100
X
XIt would kill the person whose name was in register X *10 seconds later*.`20
XPotential embarassement if you leave to have tinysex with somebody and ten
Xseconds later you kill your partner!
X
XUse instead:
X/trigger *says, "rafael's a jerk"=/copy x a\`7C/wait 10=kill \`5Ea=100
X
XNOTE: this probably won't work.  DK
XNOTE: It should now. MH
X
XNOTE from Martin Hebrank: I made some changes to the code regarding the`20
Xuse of these variables. It used to be a percent sign and not a carrot that
Xwas used, however do to extensive use of the percent sign my MU* I changed
Xit to the carrot. I think I changed all mention of it in the docs but just`2
V0
Xin case I didn't you should be aware of this. Also everything that Dave
Xsaid probably won't work should work now.
X
XSome stuff:
X-----------
X
X`09If you find what you think is a bug, look closely at what happened and
Xtell me.  Contact me either by email or on a MUD; I'm invariably rafael.
X
X`09DINK should not work with any net software but MultiNet or Wollongong.`20
XThanks to Blackwinter/Joseph Hillenburg/jph@gnu.ai.mit.edu for the Wollongon
Vg
Xport.
X
X`09Some problems will exist with substitutions, the pipe character, and
Xconflicts between triggers and gags.
X
X
X`09Good luck!
X
XCredits for version 1.0 go to:
X------------------------------
X
XTarrant (rang@cs.wisc.edu) for wrapping code that isn't used anymore.
XBlackwinter (jph@gnu.ai.mit.edu) for Wollongong code and bug testing.
XExplorer_Bob (ghudson@cie.uoregon.edu) for near-regexps and some other stuff
Xbob (amolitor@eagle.wesleyan.edu) for TINT, timer queues (and the timer queu
Ve
Xcode!) and lots of algorithm help as I learned enough C to churn out DINK an
Vd
Xupdated TINT.  Thanks, Andrew.
X
XCredits for version 2.0 go to:
X------------------------------
Xthe people who helped with version 1.0 so that I only had to change enuff
Xof the code to to update the version number. Which was quite a bit.
X
$ CALL UNPACK DINK.DOC;1 1533853657
$ create 'f'
X#include <ctype.h>
X#include <descrip>
X#include <stdio.h>
X#include <string.h>
X#define TRUE 1
X#define FALSE 0
X#define COMMAND_FILE "sys$login:dink.init"
X#define VERSION "DINK1.0"
X `20
X#define SCROLLING_REGION "\033`5B1;18r"   /* lines 0 through 18 will scroll
V */
X#define FULL_SCROLLING_REGION "\033`5B1;24r"   /* entire screen will scroll
V */
X#define ERASE_EOS "\033`5BJ"
X#define HOME "\033`5BH"
X#define SAVE_CURSOR "\0337"
X#define RESTORE_CURSOR "\0338"
X#define HILITE_ON "\033`5B1m"
X#define HILITE_OFF "\033`5B0m"
X#define CRLF "\015\012"
X#define WINDOW_X 1
X#define WINDOW_Y 18
X  /* various globals */
X `20
X  unsigned short netconnect(char *host, char *port);
Xunsigned short client_iosb`5B4`5D;
Xunsigned short term_iosb`5B4`5D;
Xunsigned short client_chan;
Xunsigned short terminal_chan;
Xint out_x,out_y,supress_next_cr,pipe_on;
Xchar word`5B80`5D;
Xint input_drawn;
Xchar client_buffer`5B5000`5D;
Xchar *ptr_term_buff;
Xchar terminal_buffer`5B1000`5D;
Xchar reg`5B27`5D`5B80`5D;
Xint col,line;
X
Xchar flag`5B`5D="BR";
Xint status`5B`5D=`7B1,1`7D;
Xchar flag_name`5B`5D`5B20`5D=`7B"bamf","result"`7D;
X
Xint log_flag;
XFILE *log_file;
X
X/* declarations of lists */
X
Xstruct gag
X`7B
X  char *name;
X  struct gag *fwd,*bwd;
X`7D *gag_list;
X
Xstruct hilite
X`7B
X  char *name;
X  struct hilite *fwd,*bwd;
X`7D *hilite_list;
X
Xstruct wait
X`7B
X  char *command;
X  int seconds;
X  struct wait *fwd,*bwd;
X`7D *wait_list;
X
Xstruct macro
X`7B
X  char *name;
X  char *equality;
X  struct macro *fwd,*bwd;
X`7D *macro_list;
X
Xstruct world
X`7B
X  char *name;
X  char *host;
X  char *port;
X  unsigned short channel;
X  struct world *fwd,*bwd;
X`7D *world_list;
X
Xstruct world *current_world;
X
Xstruct trigger
X`7B
X  char *trig;
X  char *action;
X  struct trigger *fwd,*bwd;
X`7D *trigger_list;
X
Xstruct history
X`7B
X  char *line;
X  struct history *fwd,*bwd;
X`7D *history_list;
X
Xstruct history *current_history;
Xstruct history *last_history;
$ CALL UNPACK DINK.H;1 980890865
$ create 'f'
X;
X;  This is a dink.init file. . .
X; It is used to initilize DINK the way you want it.`20
X; Just enter any command on a single line just like you would while`20
X; running dink.
X; It also allows for comments if you have a ;(semicolon) as the first`20
X; character.
X;
X;
X;/addworld fubar nauer.csuohio.edu 7719
X;/addworld acad adamwest.ins.cwru.edu 4201
X/addworld micro chezmoto.ai.mit.edu 4201
X/addworld fubar2 nauer.csuohio.edu 7719
X/addworld tiny caisr2.caisr.cwru.edu 4201
X/addworld alex mud.stacken.kth.se 4000
X/macro w=WHO
X/macro n=WHO
$ CALL UNPACK DINK.INIT;1 1259959291
$ create 'f'
Xsys$share:vaxcrtl/share
Xmultinet_root:`5Bmultinet`5Dmultinet_socket_library/share
$ CALL UNPACK DINK.OPT;1 238046520
$ create 'f'
X#define BUFSIZE 5000
X#include "dink_cmd.h"
X#include "dink.h"
X#include <ssdef.h>
X#include <jpidef.h>
X  /* command handlers */
X `20
Xinit_filters()
X`7B
X  int i;
X `20
X  for (i=0;i<27;i++) reg`5Bi`5D`5B0`5D=0;
X  gag_list=NULL;
X  hilite_list=NULL;
X  wait_list=NULL;
X  world_list=NULL;
X  trigger_list=NULL;
X`7D
X
Xchar work`5B120`5D;
X
Xcommand_handler(char *buffer)
X`7B
X  char *cmd;
X  int i;
X `20
X  /* isolate command */
X `20
X `20
X  cmd=buffer+1;
X  for(;(*buffer && !isspace(*buffer));) buffer++;
X  *buffer++='\0';
X `20
X  /* check against list */
X `20
X  for(i=0;commands`5Bi`5D.name != NULL;i++)
X    if (!strcmp(commands`5Bi`5D.name,cmd)) break;
X `20
X  if (commands`5Bi`5D.name != NULL)`20
X    return(commands`5Bi`5D.handler(buffer));
X  else print_buffer("Command not found.",1);
X`7D
X
Xml_handler ()
X`7B
X  struct macro *tmp;
X  char work`5B512`5D;
X `20
X  tmp = macro_list;
X  while (tmp != NULL)
X  `7B
X    sprintf(work,"Macro: %s defined as: %s",tmp->name,tmp->equality);
X    print_buffer(work,2);
X    if (tmp->fwd == macro_list) break;
X    tmp = tmp->fwd;
X  `7D
X`7D
X
X
Xrun_handler(char *buffer)
X`7B
X    /*runs a file as if it were typed. ;'s in the first column will`20
X      force it to ignore the whole line. buffer is assumed to be`20
X      a filename in the current directory.
X      added by Martin Hebrank              */
X
X  run_file(buffer);
X`7D
X
X
Xlist_handler()
X`7B
X   /* lists world
X      added by Martin Hebrank */
X
X  struct world *tmp;
X  char work`5B81`5D,first_name`5B80`5D;
X
X  tmp = world_list;
X `20
X  while (tmp != NULL)
X  `7B
X    sprintf (work,"World: %s at %s %s",tmp->name,tmp->host,tmp->port);
X    print_buffer(work,2);
X    if (tmp->fwd == world_list) break;
X    tmp = tmp->fwd;
X  `7D
X`7D
X `20
X
Xexit_handler()
X`7B
X   /* exits when you type "/exit"or "/quit" or "/bye"
X      added by Martin Hebrank     */
X`20
X   printf(FULL_SCROLLING_REGION);
X   move_to(20,1);
X   printf(ERASE_EOS);
X   exit(0);
X`7D
X
X
Xdump_handler(char *buffer)
X`7B
X  struct gag *tmp_gag;
X  struct hilite *tmp_hilite;
X  struct macro *tmp_macro;
X  struct wait *tmp_wait;
X  struct world *tmp_world;
X  struct trigger *tmp_trigger;
X  int i,running_total=0;
X `20
X  print_buffer("\n",0);
X  if (gag_list != NULL)`7B`20
X    print_buffer("Gagged:",1);
X    if (gag_list->fwd==gag_list) `7B
X      print_buffer(gag_list->name,0);
X    `7D
X    else `7B
X      for(tmp_gag=gag_list;;tmp_gag=tmp_gag->fwd) `7B
X`09print_buffer(tmp_gag->name,0);
X`09if (tmp_gag->fwd == gag_list) break;
X      `7D
X    `7D
X  `7D
X  if (hilite_list != NULL)`7B
X    print_buffer("Hilited:",1);
X    if (hilite_list->fwd==hilite_list) `7B
X      print_buffer(hilite_list->name,0);
X    `7D
X    else `7B
X      for(tmp_hilite=hilite_list;;tmp_hilite=tmp_hilite->fwd)
X`09`7B
X`09  print_buffer(tmp_hilite->name,0);
X`09  if (tmp_hilite->fwd == hilite_list) break;
X`09`7D
X    `7D
X  `7D
X  if (macro_list != NULL)`7B
X    print_buffer("Macros:",1);
X    if (macro_list->fwd==macro_list) `7B
X      sprintf(work,"\n%s = %s",macro_list->name,macro_list->equality);
X      print_buffer(work,0);
X    `7D
X    else `7B
X      for(tmp_macro=macro_list;;tmp_macro=tmp_macro->fwd)
X`09`7B
X`09  sprintf(work,"%s = %s",tmp_macro->name,tmp_macro->equality);
X`09  print_buffer(work,0);
X`09  if (tmp_macro->fwd == macro_list) break;
X`09`7D
X    `7D
X  `7D
X  if (wait_list != NULL) `7B
X    print_buffer("Waits:",1);
X    if (wait_list->fwd==wait_list) `7B
X      sprintf(work,"Waiting %d seconds to execute command: %s",wait_list->se
Vconds,wait_list->command);
X      print_buffer(work,1);
X    `7D
X    else `7B
X      for(tmp_wait=wait_list;;tmp_wait=tmp_wait->fwd)
X`09`7B
X`09  running_total += tmp_wait->seconds;
X`09  sprintf(work,"Waiting %d more to execute command: %s",running_total,tmp
V_wait->command);
X`09  print_buffer(work,1);
X`09  if (tmp_wait->fwd==wait_list) break;
X`09`7D
X    `7D
X  `7D
X  if (trigger_list != NULL)`7B
X    print_buffer("Triggers:",1);
X    if (trigger_list->fwd==trigger_list) `7B
X      sprintf(work,"%s triggers %s",trigger_list->trig,trigger_list->action)
V;
X      print_buffer(work,0);
X    `7D
X    else `7B
X      for(tmp_trigger=trigger_list;;tmp_trigger=tmp_trigger->fwd)
X`09`7B
X`09  sprintf(work,"%s triggers %s",tmp_trigger->trig,tmp_trigger->action);
X`09  print_buffer(work,0);
X`09  if (tmp_trigger->fwd == trigger_list) break;
X`09`7D
X    `7D
X  `7D
X  sprintf(work,"Current world: %s",current_world->name);
X  print_buffer(work,1);
X  if (world_list != NULL)`7B
X    print_buffer("Worlds:",1);
X    if (world_list->fwd==world_list) `7B
X      sprintf(work,"%s is %s port %s",world_list->name,world_list->host,worl
Vd_list->port);
X      if (world_list->channel) strcat(work, " (connected)");
X      print_buffer(work,0);
X    `7D
X    else `7B
X      for(tmp_world=world_list;;tmp_world=tmp_world->fwd)
X`09`7B
X`09  sprintf(work,"%s is %s port %s",tmp_world->name,tmp_world->host,tmp_wor
Vld->port);
X`09  if (tmp_world->channel) strcat(work, " (connected)");
X`09  print_buffer(work,0);
X`09  if (tmp_world->fwd == world_list) break;
X`09`7D
X    `7D
X  `7D
X `20
X  print_buffer("Flags:",1);
X  for(i=0;i<strlen(flag);i++)
X  `7B
X    sprintf(work,"Flag %s %s",flag_name`5Bi`5D,status`5Bi`5D ? "on" : "off")
V;
X    print_buffer(work,1);
X  `7D
X  print_buffer("End of list.",1);
X`7D
X
Xwait_handler(char *buffer)
X`7B
X  int time_in_sec,i,went_back=FALSE;
X  char *com_text,*command;
X  long time`5B2`5D;
X  struct wait *new_wait,*head,*tmp;
X `20
X  while(*buffer && *buffer==' ') buffer++;
X `20
X  com_text=buffer;
X  while(*buffer && isdigit(*buffer)) buffer++;
X  *(buffer++)=0;
X  time_in_sec=atoi(com_text);
X  if (time_in_sec < 1) `7B
X    print_buffer("Must be more than 0 seconds.",2);
X    return;
X  `7D
X  com_text=buffer;
X  while(*com_text && *com_text==' ') com_text++;
X  sprintf(work,"Waiting %d seconds to do: %s",time_in_sec,com_text);
X  print_buffer(work,2);
X `20
X  command=(char *)malloc(strlen(com_text)+1);
X  new_wait=(struct wait *)malloc(sizeof(struct wait));
X  strcpy(command,com_text);
X  new_wait->seconds=time_in_sec;
X  new_wait->command=command;
X `20
X  if (wait_list == NULL)
X    `7B
X      wait_list=new_wait;
X      new_wait->fwd=new_wait->bwd=new_wait;
X      return;
X    `7D
X `20
X  head=wait_list;
X
X  while(TRUE)
X    `7B
X      if(head->seconds <= new_wait->seconds)
+-+-+-+-+-+-+-+-  END  OF PART 2 +-+-+-+-+-+-+-+-
-+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+
X`09`7B
X`09  new_wait->seconds -= head->seconds;
X`09  head=head->fwd;
X`09  went_back=TRUE;
X`09`7D
X      else
X`09`7B
X`09  head->seconds -= new_wait->seconds;
X`09  break;
X`09`7D
X      if (head == wait_list) break;
X    `7D
X  (head->bwd)->fwd=new_wait;
X  new_wait->bwd=head->bwd;
X  head->bwd=new_wait;
X  new_wait->fwd=head;
X
X  if (!went_back) `7B
X    wait_list=new_wait;`20
X  `7D
X`7D
X
Xflag_handler(char *buffer)
X`7B
X  int offset;
X  char tmp`5B2`5D;
X  while(*buffer == ' ') buffer++;
X `20
X  while(*buffer != '\0') `7B
X    if(strchr(flag,toupper(*buffer))) `7B
X      offset=strchr(flag,toupper(*buffer))-flag;
X      status`5Boffset`5D=!status`5Boffset`5D;
X      sprintf(work,"Flag %s changed from %s to %s",
X`09      flag_name`5Boffset`5D ? "on" : "off",
X`09      !flag_name`5Boffset`5D ? "on" : "off");
X      `7D
X    else `7B
X      print_buffer("Flag not known: ",2);
X      *tmp=toupper(*buffer);
X      *(tmp+1)=(char)0;
X      print_buffer(tmp,2);
X    `7D
X    buffer++;
X  `7D
X`7D
X
Xspawn_handler(char *buffer)
X`7B
X  printf(FULL_SCROLLING_REGION);
X  printf(HOME);
X  printf(ERASE_EOS);
X  printf("Spawning.",2);
X  if (lib$spawn() != SS$_NORMAL)
X    printf("Could not spawn a subprocess.",2);
X  printf(HOME);
X  printf(SCROLLING_REGION);
X  printf(ERASE_EOS);
X  prnt_statlin();
X  out_y=out_x=1;
X`7D
X
Xatt_handler(char *buffer)
X`7B
X  typedef struct `7B
X    unsigned short buflen;
X    unsigned short code;
X    char *bufadr;
X    unsigned short *retlenadr;
X  `7D`20
X  att_list;
X  unsigned long pid;
X  unsigned short foo;
X `20
X  att_list itm`5B`5D= `7B`20
X    `7B`20
X      sizeof(unsigned long), JPI$_OWNER, &pid, &foo,`7D,
X    `7B 0,0,0,0 `7D
X  `7D;
X  if (sys$getjpiw(0,0,0,itm,0,0,0) != SS$_NORMAL) `7B
X    print_buffer("Could not attach to parent.",2);
X    return;
X  `7D
X  if (lib$attach(&pid) != SS$_NORMAL)
X    print_buffer("Could not attach to parent process.",2);
X`7D
X
Xpipe_handler(char *buffer)
X`7B
X `20
X  char prefix`5B20`5D,*end_prefix,*foo,tmp`5B1024`5D,*current,*foo_end;
X  FILE *infile;
X  char line`5B601`5D,line_send`5B601`5D,cooked`5B1024`5D;
X  int len;
X `20
X  prefix`5B0`5D=0;
X `20
X  while(*buffer && isspace(*buffer)) buffer++;
X `20
X  if (*buffer== (char) 34) `7B
X    buffer++;
X    end_prefix=strchr(buffer,(char) 34);
X    if (end_prefix == 0) `7B
X      print_buffer("No terminating quote in prefix",2);
X      return;
X    `7D
X    strncpy(prefix,buffer,end_prefix-buffer);
X    *end_prefix=0;
X    buffer=end_prefix+1;
X  `7D
X  while (*buffer && isspace(*buffer)) buffer++;
X `20
X  if ((infile= fopen(buffer,"r")) == NULL) `7B
X    sprintf(work, "Could not open filename: %s",buffer);
X    print_buffer(work,2);
X    return;
X  `7D
X `20
X  while(!(feof(infile)) && !(ferror(infile))) `7B
X    if (fgets(line,600,infile) == NULL)
X      break;
X   `20
X    foo=line;
X    while(*foo)
X      `7B
X`09if (*foo < (char) 32) *foo=0;
X`09foo++;
X      `7D
X    resolve(line,cooked);
X    strcpy(line_send,prefix);
X    strcat(line_send,cooked);
X   `20
X    if (*line_send == '/')
X      command_handler(line_send);
X    else package_line(line_send);
X  `7D
X `20
X  if ((fclose(infile)) == EOF) `7B
X    print_buffer("Error closing file.");
X    return;
X  `7D
X `20
X  sprintf(work,"Piped %s",buffer);
X  print_buffer(work,2);
X
X`7D
X
Xlog_handler(char *buffer)
X`7B
X `20
X  while(*buffer && isspace(*buffer)) buffer++;
X `20
X  if (*buffer == 0) `7B
X    if (log_flag==0) `7B
X      print_buffer("Not logging!",2);
X      return;
X    `7D
X    else `7B
X      log_flag=0;
X      print_buffer("Logging turned off.",2);
X      fclose(log_file);
X      return;
X    `7D
X  `7D
X `20
X  else `7B
X    if ((log_file=fopen(buffer,"w"))==NULL) `7B
X      sprintf(work,"Failed to open log file %s",buffer);
X      print_buffer(work,2);
X      return;
X    `7D
X   `20
X    log_flag=1;
X    sprintf(work,"Opened log file %s",buffer);
X    print_buffer(work,2);
X  `7D
X`7D
X
Xadd_handler(char *buffer)
X`7B
X  char *name,*host,*port;
X  char *new_name,*new_host,*new_port;
X  char work`5B80`5D;
X  struct world *new_world;
X `20
X  name=buffer;
X  host=strchr(buffer,' ');
X  if (host == NULL)
X    `7B
X      print_buffer("Could not parse name.",2);
X      return;
X    `7D
X  *host++=0;
X  buffer=host;
X  port=strchr(buffer,' ');
X  if (port == NULL)
X    `7B
X      print_buffer("Could not parse host name.",2);
X      return;
X    `7D
X  *port++=0;
X  lcase(buffer);
X  buffer=port;
X  while(*buffer) if (*buffer++ < (char) 30) *(buffer-1)=0;
X `20
X  new_world=(struct world *)malloc(sizeof(struct world));
X  new_name=(char *)malloc(strlen(name)+1);
X  new_host=(char *)malloc(strlen(host)+1);
X  new_port=(char *)malloc(strlen(port)+1);
X  strcpy(new_name,name);
X  strcpy(new_host,host);
X  strcpy(new_port,port);
X  new_world->name=new_name;
X  new_world->host=new_host;
X  new_world->port=new_port;
X  new_world->channel=0;
X `20
X  if (world_list==NULL) `7B   `20
X    world_list=new_world;
X    world_list->fwd=world_list->bwd=world_list;
X  `7D
X  else `7B /* insert a world into the list */
X    (world_list->bwd)->fwd=new_world;
X    new_world->bwd=world_list->bwd;
X    new_world->fwd=world_list;
X    world_list->bwd=new_world;
X  `7D
X  sprintf(work,"Added world %s at host %s port %s", new_world->name,new_worl
Vd->host,new_world->port);
X  print_buffer(work,2);
X `20
X`7D
X
Xworld_handler(char *buffer)
X`7B
X  char world`5B26`5D;
X  int count;
X  struct world *tmp;
X `20
X  while(*buffer == ' ') buffer++;
X  count=sscanf(buffer,"%s",world);
X  if (count != 1)
X    `7B
X      print_buffer("Could not parse.");
X      return;
X    `7D
X `20
X  for(tmp=world_list;;tmp=tmp->fwd)
X    `7B
X      if (!strcmp(tmp->name,world))
X`09`7B
X`09  if (tmp->channel == 0)
X`09    `7B
X`09      sprintf(work,"Trying to connect to world %s.",tmp->name);
X`09      print_buffer(work);
X`09      tmp->channel=connect_world(tmp,0);
X`09      if (tmp->channel == NULL)
X`09`09`7B
X`09`09  sprintf(work, "Failed to connect to %s",tmp->name);
X`09`09  print_buffer(work,2);
X`09`09  return;
X`09`09`7D
X`09      print_buffer("Connected.",2);
X              break;
X`09    `7D
X`09  else print_buffer("Switching.",2);
X`09  break;
X`09`7D
X      if (tmp->fwd==world_list) break;
X    `7D
X  if (strcmp(tmp->name,world))
X    `7B
X      sprintf(work,"Did not find world %s",world);
X      print_buffer(work);
X      return;
X    `7D
X `20
X  sys$cancel(current_world->channel);
X  current_world=tmp;
X  sprintf(work,"----- World %s ----- Channel %d",current_world->name,
Xcurrent_world->channel);
X  prnt_statlin();  `20
X  print_buffer(work,2);
X  if (log_flag)
X    `7B
X      fputs(work,log_file);
X    `7D
X  queue_client(current_world->channel,BUFSIZE);
X `20
X`7D
X
X
Xtrigger_handler(char *buffer)
X`7B
X  char *new_trig,*new_action,*trigger;
X  struct trigger *new_trigger,*tmp;
X `20
X  /* command format:
X     /auto trigger string=action string
X     */
X `20
X  while(isspace(*buffer)) buffer++;
X `20
X  trigger=buffer;
X  while(*buffer && *buffer != '=') buffer++;
X  if (*buffer == NULL)
X    `7B
X      print_buffer("No equality!",2);
X      return;
X    `7D
X  *buffer++=0;
X `20
X  if (trigger_list != NULL) `7B
X    for(tmp=trigger_list;;tmp=tmp->fwd)
X      `7B
X`09if (!strcmp(tmp->trig,trigger))
X`09  `7B
X`09    free(tmp->action);
X`09    new_action=(char*)malloc(strlen(buffer)+1);
X`09    strcpy(new_action,buffer);
X`09    tmp->action=new_action;
X`09    sprintf(work,"Trigger '%s' redefined as '%s'.",trigger,new_action);
X`09    print_buffer(work,2);
X`09    return;
X`09  `7D
X`09if (tmp->fwd==trigger_list) break;
X      `7D
X  `7D
X  new_trigger=(struct trigger *)malloc(sizeof(struct trigger));
X  new_trig=(char *)malloc(strlen(trigger+1));
X  new_action=(char *)malloc(strlen(buffer+1));
X  strcpy(new_trig,trigger);
X  strcpy(new_action,buffer);
X `20
X  new_trigger->trig=new_trig;
X  new_trigger->action=new_action;
X `20
X  if (trigger_list == NULL)
X    `7B
X      trigger_list=new_trigger->fwd=new_trigger->bwd=new_trigger;
X      sprintf(work,"Added action '%s' = '%s'.",new_trigger->trig,new_trigger
V->action);
X      print_buffer(work,2);
X      return;
X    `7D
X `20
X  (trigger_list->bwd)->fwd=new_trigger;
X  new_trigger->bwd=trigger_list->bwd;
X  trigger_list->bwd=new_trigger;
X  new_trigger->fwd=trigger_list;
X  sprintf(work,"Added action '%s' = '%s'",new_trigger->trig,new_trigger->act
Vion);
X  print_buffer(work,2);
X  return;
X`7D
X
X
Xcopy_handler(char *buffer)
X`7B
X  int src_reg,dst_reg;
X `20
X  while(*buffer==' ') buffer++;
X `20
X  src_reg=(int) toupper(*buffer)-64;
X  if (src_reg<1 `7C`7C src_reg>26)
X    `7B
X      print_buffer("Not a valid source register.",2);
X      return;
X    `7D
X  buffer++;
X  while(*buffer==' ') buffer++;
X  dst_reg=(int) toupper(*buffer)-64;
X  if (dst_reg<1 `7C`7C dst_reg>26)
X    `7B
X      print_buffer("Not a valid destination register.",2);
X      return;
X    `7D
X `20
X  strcpy(reg`5Bdst_reg`5D,reg`5Bsrc_reg`5D);
X  return;
X`7D
X
Xreg_handler(char *buffer)
X`7B
X  int reg_num;
X  char tmp`5B2`5D;
X
X  while(*buffer == ' ') buffer++;
X `20
X  reg_num=(int) toupper(*buffer)-64;
X  if(reg_num<1 `7C`7C reg_num>26)
X    `7B
X      print_buffer("Not a valid register.",2);
X      return;
X    `7D
X  while (*buffer != '=' && *buffer) buffer++;
X  if (*buffer==0)
X    `7B
X      print_buffer("No equality.",2);
X      return;
X    `7D
X  buffer++;
X  strcpy(reg`5Breg_num`5D,buffer);
X  tmp`5B0`5D= (char) reg_num + 96;
X  tmp`5B1`5D='\0';
X  sprintf(work,"Copied %s into register %c",buffer,tmp`5B0`5D);
X  print_buffer(work,2);
X
X`7D
X
$ CALL UNPACK DINK_CMD.C;1 554105895
$ create 'f'
X#include <stdio.h>
X/* command definitions */
X
Xint gag_handler();
Xint hilite_handler();
Xint dump_handler();
Xint ungag_handler();
Xint unhilite_handler();
Xint wait_handler();
Xint macro_handler();
Xint flag_handler();
Xint spawn_handler();
Xint att_handler();
Xint pipe_handler();
Xint log_handler();
Xint add_handler();
Xint world_handler();
Xint trigger_handler();
Xint copy_handler();
Xint reg_handler();
Xint exit_handler();
Xint list_handler();
Xint run_handler();
Xint ml_handler();
X
Xstruct command `7B
X`09char *name;
X`09int (*handler)();
X`09`7D;
X
Xstruct command commands`5B`5D=
X`7B
X`7B"gag",gag_handler`7D,
X`7B"dump",dump_handler`7D,
X`7B"hilite",hilite_handler`7D,
X`7B"ungag",ungag_handler`7D,
X`7B"unhilite",unhilite_handler`7D,
X`7B"wait",wait_handler`7D,
X`7B"macro",macro_handler`7D,
X`7B"flag",flag_handler`7D,
X`7B"spawn",spawn_handler`7D,
X`7B"att",att_handler`7D,
X`7B"pipe",pipe_handler`7D,
X`7B"log",log_handler`7D,
X`7B"addworld",add_handler`7D,
X`7B"world",world_handler`7D,
X`7B"trigger",trigger_handler`7D,
X`7B"copy",copy_handler`7D,
X`7B"reg",reg_handler`7D,
X`7B"exit",exit_handler`7D,
X`7B"quit",exit_handler`7D,
X`7B"bye",exit_handler`7D,
X`7B"listworld",list_handler`7D,
X`7B"run",run_handler`7D,
X`7B"macrolist",ml_handler`7D,
X`7BNULL,NULL`7D
X`7D;
X
$ CALL UNPACK DINK_CMD.H;1 73552329
$ create 'f'
X#include "dink.h"
X
Xchar work`5B80`5D;
X
Xextract(char *buffer)
X`7B
X  char *tmp;
X  int counter;
X `20
X  /* this function extracts the first word on an incoming line into register
V X
X     and the first number into register Y */
X `20
X  tmp=strchr(buffer,' ');
X  if (tmp) `7B
X    strncpy(reg`5B24`5D,buffer,tmp-buffer);
X    reg`5B24`5D`5Btmp-buffer`5D=0;
X  `7D
X `20
X  for(tmp=buffer;(*tmp != '\0') && (!isdigit(*tmp));) tmp++;
X  if (isdigit(*tmp)) `7B
X    for (counter=0;isdigit(*tmp);)
X      reg`5B25`5D`5Bcounter++`5D = *tmp++;
X    reg`5B25`5D`5Bcounter`5D = 0;
X  `7D
X`7D
X
Xint filter(char *buffer)
X`7B
X  struct gag *gag_tmp;
X  struct hilite *hilite_tmp;
X  char *foo;
X `20
X  if (gag_list != NULL)
X    `7B
X      for(gag_tmp=gag_list;;gag_tmp=gag_tmp->fwd)
X`09`7B
X`09  if (!smatch(gag_tmp->name,buffer))
X`09    `7B
X`09      foo=buffer;
X`09      for (;(*foo && *foo != '\012');) foo++;
X`09      supress_next_cr = (*foo != '\012');
X`09      return(2);
X`09    `7D
X`09  if (gag_tmp->fwd==gag_list) break;
X`09`7D
X    `7D
X `20
X  if (hilite_list != NULL)
X    `7B
X      for(hilite_tmp=hilite_list;;hilite_tmp=hilite_tmp->fwd)
X`09`7B
X`09  if (!smatch(hilite_tmp->name,buffer)) return(1);
X`09  if (hilite_tmp->fwd==hilite_list) break;
X`09`7D
X    `7D
X  return(0);
X`7D
X
Xistrig(char *buffer)
X`7B
X  struct trigger *trigger_tmp;
X  char action`5B1024`5D;
X `20
X  if (trigger_list != NULL)
X    `7B
X      for(trigger_tmp=trigger_list;;trigger_tmp=trigger_tmp->fwd)
X`09`7B
X`09  if (!smatch(trigger_tmp->trig,buffer))
X            `7B
X              resolve(trigger_tmp->action,action);
X`09      package_line(action);
X`09    `7D
X`09  if (trigger_tmp->fwd==trigger_list) break;
X`09`7D
X    `7D
X
X`7D
X
X
Xresolve(char *buffer, char *output)
X`7B
X    /*
X         The resolve procedure was rewritten by Martin Hebrank
X         hopefully it works better and correctly.
X         use a backslash before anything that is supposed to be
X         litteral. IOW if you want a `5E to be passed to the MU*`20
X         type \`5E or if you want a \ to be sent type \\.
X         got it?
X     */
X
X  char *tmp, *end, tmp_out`5B1024`5D, *tmp_outptr;
X  char *macro_name, *macro_tmp, *macro_out;`20
X  char *macro_out2, *reg_out, *reg_out2;
X  int i=0;
X
X  tmp = buffer;
X  end = buffer + strlen(buffer);
X  tmp_outptr= &tmp_out;
X  *tmp_outptr = '\0';
X  while (tmp < end)
X  `7B
X    while ((*tmp != '\\') && (*tmp != '`5E') && (*tmp != '`7C') && (*tmp))
X      *tmp_outptr++ = *tmp++;  /* should just copy unimportant chars to`20
X                                        output  */
X    if (*tmp == '\0')  /* if at end of nul terminated */
X    `7B
X      *tmp_outptr = '\0';  /* then null terminate the out string.  */
X      break;
X    `7D
X    else
X    `7B
X      if (*tmp == '\\')   /*  if its the litteral char */
X      `7B
X        if ((*(tmp+1) == '\\') `7C`7C (*(tmp+1) == '`7C') `7C`7C (*(tmp+1) =
V= '`5E'))
+-+-+-+-+-+-+-+-  END  OF PART 3 +-+-+-+-+-+-+-+-
-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+
X        `7B                /* check if it's supposed to pass thru  */
X          tmp++;         /* if it is then pass thru.  */
X          *tmp_outptr++ = *tmp++;
X        `7D
X        else   /* it's supposed to be a macro.  */
X        `7B
X          ++tmp;
X          macro_name = (char *) malloc(128);
X          macro_out = (char *) malloc(1024);
X          macro_out2 = (char *) malloc(1024);
X          while (*tmp >= '!' && *tmp <= '`7E' )
X          `7B
X            *(macro_name + i) = *tmp;
X            ++tmp;
X            ++i;
X          `7D
X          r_m(macro_name,macro_out);
X          resolve(macro_out,macro_out2);
X          while (*macro_out2 != '\0')
X            *tmp_outptr++ = *macro_out2++;
X        `7D
X      `7D
X      else if (*tmp == '`5E')
X      `7B
X        ++tmp;
X        reg_out = (char *) malloc(1024);
X        reg_out2 = (char *) malloc(1024);
X        r_r(*tmp,reg_out);
X        resolve(reg_out,reg_out2);
X        while (*reg_out2 != '\0')
X          *tmp_outptr++ = *reg_out2++;
X        ++tmp;
X      `7D
X      else if (*tmp == '`7C')
X      `7B
X        tmp++;
X        *tmp_outptr = '\036';
X        tmp_outptr++;
X      `7D
X    `7D
X  `7D
X  *tmp_outptr = '\0';
X  strcpy(output,tmp_out);
X`7D
X
X
Xbamf(char *buffer)
X`7B
X  char host`5B30`5D,address`5B30`5D,port`5B30`5D;
X  char work`5B120`5D,*name,addr`5B30`5D,temp`5B30`5D;
X  char *foo,ch;
X  int count;
X  struct world *tmp;
X `20
X  count = sscanf(buffer, "#### Please reconnect to %s %s port %s ####",
X`09`09 host, address, port);
X
X  if (count != 3) return;
X  name = strchr(host, '@');        /* Strip off IP address. */
X  if (name == NULL) return;
X  *name = '\0';
X `20
X  ch = *(name + 1);
X  if (isdigit(ch)) strcpy(addr, name+1);
X  else `7B
X    strcpy(temp, addr + 1);
X    strcpy(addr, temp);
X    address`5Bstrlen(addr) - 1`5D = '\0';
X  `7D
X  lcase(host);
X  print_buffer(work,2);
X `20
X  for(tmp=world_list;;)
X    `7B
X      if (!strcmp(tmp->name,host))
X`09`7B
X`09  print_buffer(work,2);
X`09  current_world->channel=0;
X`09  world_handler(host);
X`09  return;
X`09`7D
X      tmp=tmp->fwd;
X      if (tmp->fwd == world_list) break;
X    `7D
X  if (strcmp(tmp->name,host))
X    `7B
X      print_buffer(work,2);
X      sprintf(work,"%s %s %s",host,addr,port);
X      add_handler(work);
X      world_handler(host);
X    `7D
X`7D
X
Xr_m(char *macro,char *output)
X`7B`20
X  /* resolve_macro function by Martin Hebrank */
X `20
X  struct macro *tmp;
X  char *sub;
X `20
X  *output = '\0';
X  for(tmp=macro_list;;tmp = tmp->fwd)
X  `7B
X    if (!strcmp(tmp->name,macro))
X    `7B
X      for (sub=tmp->equality;*sub != '\0';)
X        *output++ = *sub++;
X      *output = '\0';
X      break;
X     `7D
X     else
X       *output = '\0';
X     if (tmp->fwd == macro_list)
X       break;
X   `7D
X`7D
X   `20
Xr_r(char reg1,char *output)
X`7B
X  /* resolve_reg function written by Martin Hebrank */
X
X  int reg_num;
X  char *sub;
X
X  *output = '\0';
X  if (isalpha(reg1))
X  `7B
X     reg_num = (int) toupper(reg1)-64;
X     for (sub = &(reg`5Breg_num`5D`5B0`5D); *sub != '\0';)
X       *output++ = *sub++;
X     *output = '\0';
X   `7D
X   else
X     *output = ' ';
X`7D     `20
$ CALL UNPACK DINK_FILT.C;1 1781201742
$ create 'f'
X#define SCROLL 18
X#include <stdio.h>
X#include <netdb.h>
X#include <in.h>
X#include <iodef.h>
X#include <socket.h>
X#include "dink.h"
X
Xqueue_terminal(unsigned short terminal_chan, char *terminal_buff,int size)
X`7B
X  sys$qio(32L,terminal_chan,IO$_TTYREADALL `7C IO$M_NOECHO,&term_iosb,
X`09  0,0,terminal_buff,size,0,0,0,0);
X`7D
X
Xqueue_client(unsigned short channel, int size)
X`7B
X  sys$qio(33L,channel,IO$_READVBLK,&client_iosb,0,0,client_buffer,
X`09  size,0,0,0,0);
X`7D
X
Xhandle_output()
X`7B
X `20
X  static char cooked_buffer`5B5000`5D;
X  char *start_ptr;
X  char *end_ptr;
X  int ret_val,result;
X  char ch,tmp`5B1024`5D;
X `20
X  client_buffer`5Bclient_iosb`5B1`5D`5D = '\0';
X
X  /* Now process it one line at a time */
X `20
X  start_ptr = client_buffer;
X  end_ptr = client_buffer;
X `20
X  do
X    `7B
X      /* Chug along to the end of this line */
X     `20
X      for(; (*end_ptr != '\0') && (*end_ptr != '\015')
X`09  && (*end_ptr != '\012');) end_ptr++;
X
X      for(;isspace(*end_ptr) && (*end_ptr != '\0');) end_ptr++;
X     `20
X      ch = *end_ptr; *end_ptr = '\0';
X      istrig(start_ptr);
X      extract(start_ptr);
X      result = status`5Bstrchr(flag,'B')-flag`5D;     `20
X      if (result) bamf(start_ptr);
X      ret_val=filter(start_ptr);
X      if (ret_val != 2)
X`09`7B
X`09  display_output(start_ptr,ret_val);
X`09  if (log_flag)
X`09    `7B
X`09    fputs(start_ptr,log_file);
X`09  `7D
X`09`7D
X      *end_ptr = ch;
X      start_ptr = end_ptr;
X    `7D
X  while(ch != '\0');
X`7D
X
Xkeyboard_handler(char *buff)
X`7B
X  char cooked`5B1024`5D,work`5B80`5D;
X  int resolve_status;
X  struct history *tmp;
X
X  if (*buff == (char) 21)  /*erase whole line with ctrl-U*/
X    `7B
X      *terminal_buffer=0;
X      ptr_term_buff=terminal_buffer;
X      line=WINDOW_Y+2;
X      col=1;
X      move_to(line,col);
X      printf(ERASE_EOS);
X    `7D
X `20
X  if (*buff == (char) 24)  /* exit with ctrl-X */
X    `7B
X      printf(FULL_SCROLLING_REGION);
X      move_to(20,1);
X      printf(ERASE_EOS);
X      exit(0);
X    `7D
X
X  if (*buff == (char) 16) /* command history: previous with ctrl-p */
X    `7B
X      if (current_history==NULL)
X`09`7B
X`09  printf("\07");
X`09  return;
X`09`7D
X
X      strcpy(terminal_buffer,current_history->line);
X      move_to(20,1);
X      printf("%s",terminal_buffer);
X      line=strlen(terminal_buffer) / 80 + 20;
X      col=strlen(terminal_buffer) % 80 + 1;
X      ptr_term_buff=terminal_buffer+strlen(terminal_buffer);
X      move_to(line,col);
X      printf(ERASE_EOS);
X      current_history=current_history->bwd;
X    `7D     `20
X
X  if (*buff == (char) 14) /* command history: next with ctrl-n*/
X    `7B
X      if (current_history==NULL) return;
X      current_history=current_history->fwd;
X      strcpy(terminal_buffer,current_history->line);
X      move_to(20,1);
X      printf("%s",terminal_buffer);
X      line=strlen(terminal_buffer) / 80 + 20;
X      col=strlen(terminal_buffer) % 80 + 1;
X      ptr_term_buff=terminal_buffer+strlen(terminal_buffer);
X      move_to(line,col);
X      printf(ERASE_EOS);
X    `7D
X
X  if (*buff == (char) 18) /* refresh buffer with ctrl-r */
X    `7B
X      move_to(20,1);
X      printf("%s",terminal_buffer);
X      move_to(line,col);
X    `7D
X
X  if (*buff == (char) 127) /* delete */
X    `7B
X      if (line == SCROLL+2 && col == 1) return;
X      *--ptr_term_buff=0;
X     `20
X      if (line == SCROLL+2)
X`09`7B
X`09  if (col > 1)
X`09    `7B
X`09      col--;
X`09      printf("\010 \010");
X`09    `7D
X`09  else return;
X`09`7D
X      else
X`09`7B
X`09  if (col > 1)
X`09    `7B
X`09      col--;
X`09      printf("\010 \010");
X`09    `7D
X`09  else
X`09    `7B
X`09      col=80;
X`09      line--;
X`09      printf("\010 \010");
X`09    `7D
X`09`7D
X      move_to(line,col);
X    `7D
X
X  if (*buff == (char) 13) /* end of line */
X    `7B
X      *(ptr_term_buff+1)=0;
X      if (ptr_term_buff == terminal_buffer) return;
X      resolve(terminal_buffer,cooked); /* this combination will send  */
X      package_line(cooked);            /* commands to command_handler */
X      add_line(terminal_buffer);
X      *terminal_buffer=0;
X      ptr_term_buff=terminal_buffer;
X      line=WINDOW_Y+2;
X      col=1;
X      move_to(line,col);
X      printf(ERASE_EOS);
X    `7D
X  if (isprint(*buff))
X    `7B
X      *ptr_term_buff++= *buff;
X      *ptr_term_buff='\0';
X      putchar(*buff);
X      col++;
X      if (col > 80)
X`09`7B
X`09  line++;
X`09  col=1;
X`09  move_to(line,col);
X`09`7D
X    `7D
X`7D
X
Xprint_buffer(char *buffer, int hilite)
X`7B
X  int result;
X  char tmp`5B80`5D;
X  if (pipe_on) return;
X
X  result = status`5Bstrchr(flag,'R')-flag`5D;
X  if (hilite == 1 `7C`7C (result && hilite)) printf(HILITE_ON);
X  if (!(result==0 && hilite==2))
X    `7B
X      move_to(out_y,1);
X      strcpy(tmp,buffer);
X      strcat(tmp,"\n");
X      output_line(tmp);
X    `7D
X  if (hilite ==1 `7C`7C (result && hilite)) printf(HILITE_OFF);
X  printf(RESTORE_CURSOR);
X`7D
X
Xpackage_line(char *buffer)
X`7B
X  char *foo,*foo_end,*current,tmp`5B1024`5D;
X `20
X  foo=buffer;
X  current=buffer;
X  foo_end=buffer+strlen(buffer);
X  while (foo <= foo_end)
X  `7B
X    while(*foo && *foo != '\036') foo++;
X    if (*foo) *foo='\0';
X    strcpy(tmp,current);
X    if (*tmp=='/')
X      command_handler(tmp);
X    else sw(tmp);
X    current= ++foo;
X  `7D
X`7D
X
Xlcase(char *buffer)
X`7B
X  while (*buffer) *buffer=tolower(*buffer++);
X`7D
X
Xmove_to(int t_line,int t_col)
X`7B
X  printf("\033`5B%d;%dH",t_line,t_col);
X`7D
X
Xchar output_screen_buffer`5B5000`5D;
Xint out_scr_buff_ptr;
X
Xdisplay_output(char *buffer, int hilite)
X`7B
X  int curr_char,i,j,sts,count;
X  int newln;
X  char ch;
X  char work_str`5B81`5D;
X `20
X  count=strlen(buffer);
X  out_scr_buff_ptr =0;
X
X  enbuffer_move_to(out_y,out_x);
X  if (hilite) enbuffer_string(HILITE_ON);
X `20
X  curr_char=0;
X  for(;count > 0;)
X    `7B
X      newln=FALSE;
X      for (;(isspace(ch=buffer`5Bcurr_char`5D)) && (count > 0);)
X`09`7B
X`09  if ((ch == '\015') `7C`7C (ch == '\012'))
X`09    `7B
X`09      newln = TRUE;
X`09    `7D
X`09  else
X`09    `7B
X`09      output_screen_buffer`5Bout_scr_buff_ptr++`5D = ' ';
X`09      out_x++;
X`09    `7D
X`09  count--;
X`09  curr_char++;
X`09`7D
X     `20
X      if (newln) newline();
X     `20
X      if (count <= 0) break;
X     `20
X      for (i=0;(i<80) && !(isspace(ch=buffer`5Bcurr_char`5D)) && (count > 0)
V;)
X`09`7B
X`09  word`5Bi++`5D = buffer`5Bcurr_char++`5D;
X`09  count--;
X`09`7D
X      if ((i+out_x) > 80) newline();
X     `20
X      out_x += i;
X      for (j=0;i>0;i--)
X`09output_screen_buffer`5Bout_scr_buff_ptr++`5D=word`5Bj++`5D;
X    `7D
X `20
X  if (hilite) enbuffer_string(HILITE_OFF);
X  output_screen_buffer`5Bout_scr_buff_ptr`5D='\0';
X  printf("%s",output_screen_buffer);
X `20
X  move_to(line,col);
X`7D
X
Xenbuffer_string(char *str)
X`7B
X  while (*str) output_screen_buffer`5Bout_scr_buff_ptr++`5D = *str++;
X`7D
X
Xenbuffer_move_to(int line, int col)
X`7B
X  char work_str`5B16`5D;
X  sprintf(work_str,"\033`5B%d;%dH",line,col);
X  enbuffer_string(work_str);
X`7D
X
Xnewline()
X`7B
X  if (supress_next_cr == 0)
X    `7B
X      out_x = 1;
X      out_y = (out_y >= 18 ? 18 : out_y + 1);
X      enbuffer_string(CRLF);
X    `7D
X  else
X    `7B
X      supress_next_cr = 0;
X    `7D
X`7D
X
Xoutput_line(char *buffer)
X`7B
X
X  out_y++;
X  if (out_y > 18 ) out_y = 18;
X  printf("%s",buffer);
X
X`7D
X
Xadd_line(char *line)
X`7B
X  struct history *tmp;
X
X  /* add current command to list, then page back. */
X
X      if (history_list==NULL)
X`09`7B
X`09  history_list=(struct history *)malloc(sizeof(struct history));
X`09  tmp=history_list;
X`09  tmp->line=malloc(strlen(line));
X`09  tmp->fwd=tmp->bwd=history_list;
X`09  last_history=current_history=history_list;
X`09  strcpy(tmp->line,line);
X`09  return;
X`09`7D
X `20
X  tmp=(struct history *)malloc(sizeof(struct history));
X  tmp->bwd=last_history;
X  last_history->fwd=tmp;
X  last_history=tmp;
X  tmp->fwd=history_list;
X  tmp->line=malloc(strlen(line));
X  strcpy(tmp->line,line);
X  current_history=tmp;
X  return;
X`7D
X
Xprnt_statlin()
X`7B
X  /* prints the status line on line 19.
X      add by Martin Hebrank             */
X
X   move_to(19,1);
X   printf ("___ World: %s ____________________________", current_world->name
V);
X`7D
X
Xrun_file(char filname`5B`5D)
X`7B
X    /* reads the file filname`5B`5D from the current directory and executes
X       it as if it were typed from the keyboard.
X        also added by Martin Hebrank                               */
X
X  FILE *run_file;
X  char buff`5B1024`5D,work`5B81`5D,buff2`5B1024`5D;
X`20
X  if ((run_file = fopen(filname,"r")) != NULL)
X  `7B
X    while (!(feof(run_file)) && !(ferror(run_file)))
X    `7B
X        if ((fgets (buff,512,run_file)) != NULL)
X        `7B
X          if (*buff != ';')
X          `7B
X            resolve(buff,buff2);
X            package_line(buff2);
X          `7D
X        `7D
X        else
X          break;
X     `7D
X     fclose(run_file);
X  `7D
X`7D
X
X
$ CALL UNPACK DINK_FUNC.C;1 373098565
$ create 'f'
X#include <stdio.h>
X#include "dink.h"
Xgag_handler(char *buffer)
X`7B
X  char *name;
X  struct gag *new_gag;
X  int i;
X `20
X  /* parse from first quote to last quote and copy that into text */
X `20
X  while(*buffer==' ') buffer++;
X `20
X  new_gag=(struct gag *)malloc(sizeof(struct gag));
X  name=(char *)malloc(strlen(buffer)+1);
X  strcpy(name,buffer);
X  new_gag->name=name;
X `20
X  if (gag_list==NULL) `7B
X    gag_list=new_gag;
X    gag_list->fwd=gag_list->bwd=gag_list;
X  `7D
X  else `7B /* insert a gag into the list */
X    (gag_list->bwd)->fwd=new_gag;
X    new_gag->bwd=gag_list->bwd;
X    new_gag->fwd=gag_list;
X    gag_list->bwd=new_gag;
X  `7D
X  print_buffer("Gagged.",2);
X`7D
X
Xungag_handler(char *buffer)
X`7B
X  char *name;
X  struct gag *tmp;
X `20
X  while(*buffer==' ') buffer++;
X `20
X  if (gag_list==NULL) print_buffer("Nothing gagged.",2);
X  else `7B
X    for(tmp=gag_list;;tmp=tmp->fwd)
X      if (!(strcmp(tmp->name,buffer)) `7C`7C
X`09  tmp->fwd==gag_list) break;
X    if (strcmp(tmp->name,buffer))
X      print_buffer("Not found.",2);
X    else `7B
X      free(tmp->name);
X     `20
X      if (tmp->fwd==tmp) gag_list=NULL;
X      else `7B
X`09(tmp->bwd)->fwd=tmp->fwd;
X`09(tmp->fwd)->bwd=tmp->bwd;
X`09if (tmp==gag_list) gag_list=tmp->fwd;
X      `7D
X      free(tmp);
X      print_buffer("Ungagged.",2);
X    `7D
X  `7D
X`7D
$ CALL UNPACK DINK_GAG.C;1 1160735900
$ create 'f'
X#include <stdio.h>
X#include "dink.h"
X `20
Xhilite_handler(char *buffer)
X`7B
X  char *name;
X  struct hilite *new_hilite;
X `20
X  while(*buffer==' ') buffer++;
X `20
+-+-+-+-+-+-+-+-  END  OF PART 4 +-+-+-+-+-+-+-+-
-+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+
X  new_hilite=(struct hilite *)malloc(sizeof(struct hilite));
X  name=(char *)malloc(strlen(buffer)+1);
X  strcpy(name,buffer);
X  new_hilite->name=name;
X `20
X  if (hilite_list==NULL) `7B
X    hilite_list=new_hilite;
X    hilite_list->fwd=hilite_list->bwd=hilite_list;
X  `7D
X  else `7B /* insert a hilite into the list */
X    (hilite_list->bwd)->fwd=new_hilite;
X    new_hilite->bwd=hilite_list->bwd;
X    new_hilite->fwd=hilite_list;
X    hilite_list->bwd=new_hilite;
X  `7D
X  print_buffer("Hilited.",2);
X`7D
X
Xunhilite_handler(char *buffer)
X`7B
X  char *text,*name;
X  struct hilite *tmp;
X `20
X  /* parse from first quote to last quote and copy that into text */
X `20
X  while(*buffer==' ') buffer++;
X `20
X  if (hilite_list==NULL) print_buffer("Nothing hilited.",2 );
X  else `7B
X    for(tmp=hilite_list;;tmp=tmp->fwd)
X      if (!(strcmp(tmp->name,buffer)) `7C`7C
X`09  tmp->fwd==hilite_list) break;
X    if (strcmp(tmp->name,buffer))
X      print_buffer("Not found.",2);
X    else `7B
X      free(tmp->name);
X     `20
X      if (tmp->fwd==tmp) hilite_list=NULL;
X      else `7B
X`09(tmp->bwd)->fwd=tmp->fwd;
X`09(tmp->fwd)->bwd=tmp->bwd;
X`09if (tmp==hilite_list) hilite_list=tmp->fwd;
X      `7D
X      free(tmp);
X      print_buffer("Unhilited.",2);
X    `7D
X  `7D
X`7D
X
X
$ CALL UNPACK DINK_HILITE.C;1 678394737
$ create 'f'
X#include <stdio.h>
X#include "dink.h"
X
Xchar work`5B80`5D; `20
Xmacro_handler(char *buffer)
X`7B
X  char *name,*text,*equality,*new_name,*new_equality;
X  struct macro *new_macro,*tmp;
X `20
X  name=buffer;
X  text=strchr(name,'=');
X  if (text==0) print_buffer("No equality.");
X  else `7B
X    *text++=0;
X    equality=text;
X    if (*text == 0) print_buffer("Macro must have text equality.");
X    else `7B
X      if (macro_list != NULL) `7B
X`09for(tmp=macro_list;;tmp=tmp->fwd) `7B
X`09  if (strcmp(tmp->name,name)==0) `7B
X`09    free(tmp->equality);
X`09    new_equality=(char*)malloc(strlen(equality)+1);
X`09    strcpy(new_equality,equality);
X`09    tmp->equality=new_equality;
X`09    sprintf(work,"Macro '%s' redefined as '%s'",name,new_equality);
X`09    print_buffer(work,2);
X`09    return;
X`09  `7D
X`09  if (tmp->fwd==macro_list) break;
X`09`7D
X      `7D
X     `20
X      new_name=(char *)malloc(strlen(name)+1);
X      new_equality=(char *)malloc(strlen(equality)+1);
X      new_macro=(struct macro *)malloc(sizeof(struct macro));
X     `20
X      strcpy(new_name,name);
X      strcpy(new_equality,equality);
X      new_macro->name=new_name;
X      new_macro->equality=new_equality;
X     `20
X      if(macro_list==NULL) `7B
X`09macro_list=new_macro->fwd=new_macro->bwd=
X`09  new_macro;
X      `7D
X      else `7B
X`09(macro_list->bwd)->fwd=new_macro;
X`09new_macro->bwd=macro_list->bwd;
X`09new_macro->fwd=macro_list;
X`09macro_list->bwd=new_macro;
X      `7D
X      sprintf(work,"Macro '%s' defined as '%s'",new_name,new_equality);
X      print_buffer(work,2);
X    `7D
X  `7D
X`7D
X
$ CALL UNPACK DINK_MACRO.C;1 1668938647
$ create 'f'
X#include <stdio.h>
X#define TRUE 1
X#define FALSE 0
X
X/* the follow matching code and string handlers are stolen shamelessly from
XTinyFugue, credit to Explorer_Bob (ghudson@cie.uoregon.edu) */
X
Xchar *estrchr(s, c, e)
X    char *s, c, e;
X`7B
X    while (*s) `7B
X        if (*s == c) break;
X        if (*s == e) s++;
X        if (*s) s++;
X    `7D
X    if (*s) return s;
X    else return NULL;
X`7D
X
Xchar *cstrstr(s1, s2)
X    char *s1, *s2;
X`7B
X    char *temp = s1;
X    int len = strlen(s2);
X
X    while (temp = strchr(temp,*s2)) `7B
X        if (!cstrncmp(temp,s2,len)) return temp;
X        else temp++;
X    `7D
X    return NULL;
X`7D
X
Xint cstrcmp(s, t)
X    char *s, *t;
X`7B
X    while (*s && *t && tolower(*s) == tolower(*t)) `7B
X        s++;
X        t++;
X    `7D
X    return (tolower(*s) - tolower(*t));
X`7D
X
Xint cstrncmp(s, t, n)
X    char *s, *t;
X    int n;
X`7B
X    while (n-- && *s && *t && tolower(*s) == tolower(*t)) `7B
X        s++;
X        t++;
X    `7D
X    if (n <= 0) return 0;
X    else return (tolower(*s) - tolower(*t));
X`7D
X
Xchar *strdup(s)
X    char *s;
X`7B
X    char *p;
X
X    p = (char *) malloc(strlen(s) + 1);
X    strcpy(p, s);
X    return p;
X`7D
X
X#define test(x) if (tolower(x) == c1) return truthval
X/* Watch if-else constructions */
X
Xstatic int cmatch(s1, c1)
X    char *s1, c1;
X`7B
X    int truthval = FALSE, i;
X
X    c1 = tolower(c1);
X    if (*s1 == '`5E') `7B
X        s1++;
X        truthval = TRUE;
X    `7D
X    if (*s1 == '-') test(*s1++);
X    while (*s1) `7B
X        if (*s1 == '\\' && *(s1 + 1)) s1++;
X        if (*s1 == '-') `7B
X            char c, start = *(s1 - 1), end = *(s1 + 1);
X
X            if (start > end) `7B
X`09`09test(*s1++);
X`09    `7D else `7B
X                for (c = start; c <= end; c++) test(c);
X                s1 += 2;
X            `7D
X        `7D else test(*s1++);
X    `7D
X    return !truthval;
X`7D
X
Xstatic int wmatch(wlist, s2)
X    char *wlist;     /* word list                      */
X    char **s2;       /* buffer to match from           */
X`7B
X    char *matchstr,  /* which word to find             */
X         *strend,    /* end of current word from wlist */
X         *matchbuf,  /* where to find from             */
X         *bufend;    /* end of match buffer            */
X    int  result = 1; /* intermediate result            */
X
X    if (!wlist `7C`7C !*s2) return 1;
X    matchbuf = *s2;
X    matchstr = wlist;
X    bufend = strchr(matchbuf,' ');
X    if (bufend == NULL) *s2 += strlen(*s2);
X    else `7B
X        *s2 = bufend;
X        *bufend = 0;
X    `7D
X    do `7B
X        if ((strend = estrchr(matchstr,'`7C','\\')) != NULL)
X            *strend = '\0';
X        result = smatch(matchstr,matchbuf);
X        if (strend != NULL) *strend++ = '`7C';
X        if (!result) break;
X    `7D while ((matchstr = strend) != NULL);
X    if (bufend != NULL) *bufend = ' ';
X    return result;
X`7D
X
Xint smatch(s1, s2)
X    char *s1, *s2;
X`7B
X    char ch, *start = s2;
X
X
X    while (*s1) `7B
X        switch (*s1) `7B
X        case '\\':
X            s1++;
X            if (tolower(*s1++) != tolower(*s2++)) return 1;
X            break;
X        case '?':
X            if (!*s2++) return 1;
X            s1++;
X            break;
X        case '*':
X            while (*s1 == '*' `7C`7C (*s1 == '?' && *s2++)) s1++;
X            if (*s1 == '?') return 1;
X            if (*s1 == '`7B') `7B
X                if (s2 == start) if (!smatch(s1,s2)) return 0;
X                while ((s2 = strchr(s2,' ')) != NULL)
X                    if (!smatch(s1,++s2)) return 0;
X                return 1;
X            `7D else if (*s1 == '`5B') `7B
X                while (*s2) if (!smatch(s1,s2++)) return 0;
X                return 1;
X            `7D
X            if (*s1 == '\\') ch = *(s1 + 1);
X            else ch = *s1;
X            while ((s2 = strchr(s2,ch)) != NULL) `7B
X                if (!smatch(s1,s2)) return 0;
X                s2++;
X            `7D
X            return 1;
X        case '`5B':
X            `7B
X                char *end;
X
X                if (!(end = estrchr(s1,'`5D','\\'))) `7B
X                    puts("% smatch: unmatched '`5B'");
X                    return 1;
X                `7D
X                *end = '\0';
X                if (cmatch(s1 + 1,*s2++)) `7B
X                    *end = '`5D';
X                    return 1;
X                `7D
X                *end = '`5D';
X                s1 = end + 1;
X            `7D
X            break;
X        case '`7B':
X            if (s2 != start && *(s2 - 1) != ' ') break;
X            `7B
X                char *end;
X
X                if (!(end = estrchr(s1,'`7D','\\'))) `7B
X                    puts("% smatch: unmatched '`7B'");
X                    return 1;
X                `7D
X                *end = '\0';
X                if (wmatch(s1 + 1,&s2)) `7B
X                    *end = '`7D';
X                    return 1;
X                `7D
X                *end = '`7D';
X                s1 = end + 1;
X            `7D
X            break;
X        default:
X            if(tolower(*s1++) != tolower(*s2++)) return 1;
X            break;
X        `7D
X    `7D
X    return tolower(*s1) - tolower(*s2);
X`7D
X
$ CALL UNPACK DINK_MATCH.C;2 525346157
$ create 'f'
Xsys$share:vaxcrtl/share
Xmultinet_root:`5Bmultinet`5Dmultinet_socket_library/share
$ CALL UNPACK DINK_MULTINET.OPT;1 238046520
$ create 'f'
X#include "dink.h"
X#include <stdio.h>
X
X#if defined (MULTINET)
X#  include "multinet_root:`5Bmultinet.include.sys`5Dtypes.h"
X#  include "multinet_root:`5Bmultinet.include.sys`5Dsocket.h"
X#  include "multinet_root:`5Bmultinet.include.netinet`5Din.h"
X#  include "multinet_root:`5Bmultinet.include`5Dnetdb.h"
X#  define SOCKET_CLOSE socket_close
X#  define SOCKET_PERROR socket_perror
X#  define SOCKET_WRITE socket_write
X#elif defined (WOLLONGONG)
X#  include "twg$tcp:`5Bnetdist.include.sys`5Dtypes.h"
X#  include "twg$tcp:`5Bnetdist.include.sys`5Dsocket.h"
X#  include "twg$tcp:`5Bnetdist.include.netinet`5Din.h"
X#  include "twg$tcp:`5Bnetdist.include`5Dnetdb.h"
X#  define SOCKET_CLOSE close
X#  define SOCKET_PERROR perror
X#  define SOCKET_WRITE netwrite
X#else
X#  define SOCKET_CLOSE "You doof, you're using an unsupported networking sys
Vtem!"
X#  define SOCKET_PERROR "You doof, you're using an unsupported networking sy
Vstem!"
X#  define SOCKET_WRITE "You doof, you're using an unsupported networking sys
Vtem!"
X#endif
X
X#include <iodef.h>
X `20
X `20
X  /* Given host and port, makes a connection */
X  /*    Returns 0 on failure, else channel connected to */
X  unsigned short connect_world (struct world *world_info,int disconnect)
X`7B
X  struct sockaddr_in sin;
X  struct hostent *hp=0;
X  struct servent *sp=0;
X  char localhost`5B34`5D;
X  unsigned short int chan;
X  char *name,*host,*port;
X `20
X  host=world_info->host;
X  port=world_info->port;
X  if (disconnect == 1)
X    `7B
X      SOCKET_CLOSE(current_world->channel);
X    `7D
X `20
X  /* Zero the sin structure to initialize it */
X  bzero((char *) &sin, sizeof(sin));
X  sin.sin_family = AF_INET;
X `20
X  /* Lookup the host and initialize sin_addr */
X  /* If no host specified, use local address */
X  if ((host == 0) `7C`7C (host`5B0`5D == '\0')) `7B
X    if (gethostname(localhost,sizeof(localhost))<0) `7B
X      fprintf(stderr,"Unable to find localhost.\n");
X      return(0);
X    `7D           `20
X    hp = gethostbyname(localhost);
X  `7D`20
X  else `7B
X    hp = gethostbyname(host);
X  `7D
X  /* Host not name, try treating it as octets */
X  if (!hp) `7B     `20
X    if ((sin.sin_addr.s_addr = inet_addr(host)) == -1) `7B
X      fprintf(stderr,"Unknown internet host.\n");
X      return(0);
X    `7D
X  `7D`20
X  else `7B
X    bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);
X  `7D
X `20
X  /* Lookup the port */
X  if ((port == 0) `7C`7C (port`5B0`5D == '\0')) `7B
X    sp = getservbyname("telnet", "tcp");        /* default */
X  `7D`20
X  else `7B
X    sp = getservbyname(port, "tcp");            /* by name */
X  `7D      `20
X  if (sp == NULL) `7B                               /* maybe by number? */
X    unsigned short nport;
X   `20
X    nport = atol(port);
X    if (nport == 0) `7B
X      fprintf(stderr,"Unknown port.\n");
X      return(0);
X    `7D
X    sin.sin_port = htons(nport);
X  `7D`20
X  else `7B  `20
X    sin.sin_port = sp->s_port;
X  `7D
X `20
X  /* Assign socket */
X  chan = socket(sin.sin_family, SOCK_STREAM, 0);
X  if (chan < 0) `7B
X    SOCKET_PERROR("socket");
X    return(0);
X  `7D
X `20
X  /* Connect */
X  if (connect(chan, &sin, sizeof(sin),0) < 0) `7B
X    SOCKET_PERROR("connect");
X    return(0);
X  `7D
X  return(chan);
X`7D
Xsw(char *buffer)
X`7B
X  int size;
X  char send`5B1024`5D;
X `20
X  strcpy(send,buffer);
X  size=strlen(send);
X  send`5Bsize++`5D= (char) 13;
X  send`5Bsize++`5D= (char) 10;
X  SOCKET_WRITE(current_world->channel,&send,size);
X`7D
$ CALL UNPACK DINK_NET.C;1 169714254
$ create 'f'
X#include "dink.h"
X#include <libdtdef.h>
X#define BUFSIZE 5000
X  /* DINK_RUN.C */
X `20
Xdink()
X`7B
X  char *buff,single_char;
X  int op=LIB$K_DELTA_SECONDS,sec=1;
X  long bin_time`5B2`5D;
X  struct wait *tmp;
X `20
X  buff= &single_char;
X  ptr_term_buff=terminal_buffer;
X `20
X  input_drawn=TRUE;
X  queue_terminal(terminal_chan,buff,1);
X  queue_client(current_world->channel,BUFSIZE);
X  lib$cvt_to_internal_time(&op,&sec,bin_time);
X  sys$setimr(34L,bin_time,0,0);
X  line=WINDOW_Y+2;
X  col=1;
X `20
X  prnt_statlin();    /*should print the status line */
X
X  for(;;) `7B
X    sys$wflor(32L,7L);
X   `20
X    if (term_iosb`5B0`5D != 0)`20
X    `7B
X      keyboard_handler(buff);
X      queue_terminal(terminal_chan,buff,1);
X    `7D
X   `20
X    else if (client_iosb`5B0`5D != 0)`20
X    `7B
X      handle_output(terminal_buffer);
X      queue_client(current_world->channel,BUFSIZE);
X    `7D
X   `20
X    else if (client_iosb`5B0`5D ==0 && term_iosb`5B0`5D == 0)`20
X    `7B
X      /* timer queue */
X      if (wait_list != NULL)
X      `7B
X`09if (--(wait_list->seconds) == 0) `7B
X`09  package_line(wait_list->command);
X`09  free(wait_list->command);
X`09  if (wait_list->fwd != wait_list) `7B
X`09    (wait_list->fwd)->bwd=wait_list->bwd;
X`09    (wait_list->bwd)->fwd=wait_list->fwd;
X`09    wait_list=wait_list->fwd;
X`09  `7D
X`09  else wait_list=NULL;
X`09  if (wait_list != NULL)
X`09  `7B
X`09    for(tmp=wait_list;tmp->seconds == 0;tmp=tmp->fwd)
X`09      `7B
X`09`09package_line(wait_list->command);
X`09`09free(wait_list->command);
X`09`09if (wait_list->fwd != wait_list)
X`09`09  `7B
X`09`09  (wait_list->fwd)->bwd=wait_list->bwd;
X`09`09  (wait_list->bwd)->fwd=wait_list->fwd;
X`09`09  wait_list=wait_list->fwd;
X`09`09  `7D
X`09`09else wait_list=NULL;
X`09      `7D
X`09  `7D
X`09`7D
X      `7D
X      sys$setimr(34L,bin_time,0,0);
X    `7D
X  `7D
X`7D
$ CALL UNPACK DINK_RUN.C;1 7022553
$ create 'f'
Xsys$share:vaxcrtl/share
Xtwg$tcp:`5Bnetdist.lib`5Dtwglib.olb/lib
$ CALL UNPACK DINK_WOLLONGONG.OPT;1 830105629
$ create 'f'
X$! MAKEDINK.COM
X$!   Sole arguement being TCP/IP system which you are compiling for.
+-+-+-+-+-+-+-+-  END  OF PART 5 +-+-+-+-+-+-+-+-
-+-+-+-+-+-+-+-+ START OF PART 6 -+-+-+-+-+-+-+-+
X$!   Valid arguements are WOLLONGONG and MULTINET
X$ IF P1 .EQS. ""
X$   THEN
X$     WRITE SYS$OUTPUT "Usage: @MAKEDINK.COM <TCPIP_SYSTEM>"
X$     WRITE SYS$OUTPUT "TCPIP_SYSTEM is either WOLLONGONG or MULTINET."
X$     EXIT
X$ ENDIF
X$ WR :== WRITE SYS$OUTPUT
X$ CURDIR = F$ENVIRONMENT("DEFAULT")
X$ WR "Compiling DINK for ''P1'..."
X$ WR "  dink.c..."
X$ cc dink
X$ WR "  dink_run..."
X$ cc dink_run
X$ WR "  dink_net..."
X$ cc dink_net/define=('P1')
X$ WR "  dink_func..."
X$ cc dink_func
X$ WR "  dink_cmd..."
X$ cc dink_cmd
X$ WR "  dink_gag..."
X$ cc dink_gag
X$ WR "  dink_hilite..."
X$ cc dink_hilite
X$ WR "  dink_match..."
X$ cc dink_match
X$ WR "  dink_macro..."
X$ cc dink_macro
X$ WR "  dink_filt..."
X$ cc dink_filt
X$ WR "Linking DINK..."
X$ link/exe=dink.exe dink,dink_run,dink_net,dink_func,dink_cmd,dink_match, -
Xdink_hilite,dink_gag,dink_macro,dink_filt,dink_'P1'.opt/opt
X$ WR "Finished...to use, add the following to your SYS$LOGIN:LOGIN.COM:"
X$ WR "$ DINK :== $ ''CURDIR'DINK.EXE"
X$ EXIT
X
$ CALL UNPACK MAKEDINK.COM;1 895571243
$ create 'f'
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
X
X
XYou must be using either Multinet or Wollongong TCP/IP software to`20
Xuse this client.
X
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
X
X
XTo compile this type either:
X
X@makedink wollongong
X
Xif you have the Wollongong software, or:
X
X@makedink multinet
X
Xif you have the Multinet software
$ CALL UNPACK README.;1 1127743931
$ v=f$verify(v)
$ EXIT