[comp.sys.amiga] Aux: Handler

drew@cgou01.dec.com (Steve Drew) (05/08/87)

Here's my first attempt at a dos handler. Please read the docs!!
I wrote in support for ACTION_SCREEN_MODE originally thinking that
my commandline editing under shell would work ok through AUX: to 
a vt100 style terminal. But alas some of the escape sequences I used
under shell (for inserting / deleting char's) were Amiga specific
and not ansi sequences. So as a quick alternative I added a switch
to shell to turn of CLE for use over AUX:. 

But with the capability of RAW mode you could write/modify a ansi
style screen editor that would also work through aux-handler to a
ansi style terminal. Any volunteers?

Following the dos's and executable are the sources.

< I code because I enjoy getting frustrated!! >

Please email me any bugs found to:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 	Steve Drew at	ENET:    CGFSV1::DREW
    			ARPA:    drew%cfgsv1.dec.com@decwrl.dec.com
    			USENET:  {decvax!decwrl}!cgfsv1.dec.com!drew    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	aux.doc
#	mountlist
#	aux-handler.uue
# This archive created: Fri May  8 09:53:32 1987
echo shar: extracting aux.doc
cat << \SHAR_EOF > aux.doc

 Aux-Handler V1.0 	(c) Steve Drew 1987
 ----------------

I.  Desciption:

     - Installs as a dos handler to control the serial port as a console.
     - Support all relevent dos packets including WaitForChar and 
       ACTION_SCREEN_MODE. 
     - To your process it looks just like a CON: handler, screening 
       control chars doing CRLF translations and handling deletes ect...
     - Can be made into a RAW console via ACTION_SCREEN_MODE, it then
       acts like a RAW console which does not echo characters or handle
       control chars, but just passes all keys entered back to the process.
       This would allow you to implement a ANSI style screen editor like
       maybe MicroEMACS 3.x to work through AUX:. Now thats a multiuser
       system!
 
II.  Installation:
 
     1. Insert the included MOUNTLIST file into you DEVS:MOUNTLST

     2. Copy the Aux-Handler to the l: directory

     3. Enter Mount AUX: to load the driver.


III  Using

     - 'NEWCLI AUX:' will start a cli on the Serial port.	

     - <BS> <DEL> both delete last char typed.
 
     - ^X or ^U delete entire line.

     - ^S / ^Q stop/start screen display (if XON/XOFF selected under prefs.)

IV   Notes:

     - Setups':    
		The Aux-Handler opens the serial port with its current
		settings (as set up in preferences).
		However you may specify if you want ECHO, CRLF, or
		RAW Mode on/off via specifiying keyword 'Set':
			Newcli AUX:Set/E:[On/Off]/C:[On/Off]/R:[On/Off]
		for example to set Raw off, Echo off and CRLF on.
			Newcli AUX:Set/e:off/c:on/r:off
	        
		Case is insensitive. The default if any parameters
		not specified is:
			Echo ON, Raw Off, CRLF ON.
	
     - Killing A CLI:
		Normally you just do a ENDCLI. However if you had
		some one in over a modem or fired it up by mistake
		you can force an ENDCLI command to be sent to the
		process by doing a 'ECHO >AUX:ENDCLI' from another
		CLI.
	
SHAR_EOF
if test 1913 -ne "`wc -c aux.doc`"
then
echo shar: error transmitting aux.doc '(should have been 1913 characters)'
fi
echo shar: extracting mountlist
cat << \SHAR_EOF > mountlist

/*  
	Installs Aux-Handler V 1.0 (C) Steve Drew    
*/

AUX:       Handler = L:Aux-Handler
           Stacksize = 4000
           Priority = 5
	   GlobVec = 1
#
SHAR_EOF
if test 162 -ne "`wc -c mountlist`"
then
echo shar: error transmitting mountlist '(should have been 162 characters)'
fi
echo shar: extracting aux-handler.uue
cat << \SHAR_EOF > aux-handler.uue
begin 777 aux-handler
M   #\P         #          (   2<     0   !@   /I   $G$[Z#K!.
M50  (&T ""\H ! B;0 (+RD #"\M  PO+0 (80A/[P 03EU.=4Y5__@@;0 (
M(6T $  ,(&T ""%M !0 $"!M  @K:  $__@@;0 (*U#__"!M  @@+0 ,T+P 
M  !<(4  !"!M__PA;0 (  H@;?_\0I @;?_\0J@ !"\M__PO+?_X3KD  !("
M4$].74YU3E7_^" M  C0O    %PK0/_\+RW__$ZY   27%A/+RW__$ZY   1
MQ%A/*T#_^"!M__@@*  *3EU.=4Y5_LA!^@5$*TC__"M\     ?_@0JW_T$*G
M3KD  !&*6$\K0/_X+RW_^$ZY    DEA/*T#_]"!M__0@*  <Y8 K0/_L(&W_
M[" M__C0O    %PA0  (("W_^-"\    7"M _^0@;?_T+R@ $$AX__\O+?_X
M+RW_]$ZY    *D_O !!"N0   ")"N0   "9"N0   "I"N0   !I*K?_@9P $
MGDJM_]!G  $ (&W_Y'  $"@ #W(!X:$B>0    HL:0 .=  4+@ /=@'EHX*#
M+'D    6=@ 6+@ /= 'GHH*"+P%.N0  $D!83RM _LP@>0   !9P ! H  ]R
M >&APJW^S&<N+SD    23KD  !).6$\(N0 $    )2!M__!"J  ,+RW_^"\M
M__!.N0    103R!Y    "B)H  YP ! I  ]R >&APJW^S&<P+SD    *3KD 
M  ^P6$]*@&<>2&W^T$ZZ!Q!83R\M__@O+?_P2&W^T$ZZ!5Q/[P ,(&W_Y'  
M$"@ #W(!X:'"K?[,9Q(O+?_X3KD   "26$\K0/_T8 1@ /[V8! O+?_X3KD 
M  "26$\K0/_T(&W_]" H  A@  ,\2KD    :9QQ(> #*0J<O+?_X+RW_]$ZY
M    *D_O !!@  -42JW_T&8H3KH))"M _]!F'$AX ,I"IR\M__@O+?_T3KD 
M   J3^\ $&   RA@!%*M_] @;?_T("@ '.6 *T#_W$AX  $@;?_<<  0$%* 
M+P!.N0  $5Q03RM _]@@;?_<<  0$"\ +RW_V")M_]Q2B2\)3KD   \X3^\ 
M#"!M_]QP ! 0(FW_V$(Q"  K;?_8_]1@'B!M_]00$$B 2, O $ZY   .@EA/
M(&W_U!" 4JW_U"!M_]1*$&;:2'H"PB\M_]A.N0  #V)03TJ 9D0(.0 #    
M)6<Z2'H"KR!M__ O*  83KD   ^24$\@;?_P(7P    '  PO+?_X+RW_\$ZY
M    !%!/"+D  P   "5@"B\M_]A.N@)Z6$\@;?_<<  0$%* +P O+?_83KD 
M !&>4$\@;?_T("@ %.6 *T#_Z"!M_^@A?/____\ )"!M_^@A?/____\ !$JY
M    &F8R(&W_] RH   #[0 (9B0@;?_T*V@ !/[((&W^R"/H !     :(&W^
MR")M_^@C:  0 "0@;?_T+R@ $$AX__\O+?_X+RW_]$ZY    *D_O !!@  &>
M*VW_]/_P"/D  P   "4O+?_X+RW_\$AM_M!.N@,83^\ #&   7@@;?_T+R@ 
M'")M__0O*0 83KH&L%!/(&W_]")M__0C:  <  PO+?_X+RW_]$ZY    !%!/
M8  !0"MM__3_\ CY  0    E('D    20J@ ("!M__ B>0   !(C:  4 "0O
M.0   !).N0  $B!83R\M__@O+?_P2&W^T$ZZ I)/[P ,8   \B!M__1*J  4
M9Q((^0 "    )0BY       E8! (N0 "    )0CY       E3KH"6B!M__0O
M*  02'C__R\M__@O+?_T3KD    J3^\ $&   *!3K?_09@Q"K?_@3KH(O$ZZ
M"#0@;?_T(#D    :L*@ %&8&0KD    :(&W_]"\H !!(>/__+RW_^"\M__1.
MN0   "I/[P 08%9(> #10J<O+?_X+RW_]$ZY    *D_O !!@/)"\    %&< 
M_O:0O    #YG /Z.6X!G /ZND+P   .+9P#_*I"\    "V< _)I3@&< _+A3
M@&< _V9@JF  ^UX@;?_L0J@ "$Y=3G5697(@,2XP("AC*2!3=&5V92!$<F5W
M(#$Y.#< 0558.D5.1$-,20!%3D1#3$D*  !.5?_P*WP    !__!(>  (2'H 
M_"\M  A.N0  #VA/[P ,2H!G!$Y=3G4@+0 (4( K0/_\2JW_\&<  - K;?_\
M__A@!%*M__P@;?_\2A!G"B)M__P,$0 O9NH@;?_\2A!F!$*M__ @;?_\0A @
M+?_X5( K0  ((&W__+'M  AC  ""(&W_^! 02(!(P& D*WP    !__1@,"M\
M     O_T8"8K?     3_]& <0JW_]& 6D+P   !#9]Y5@&?0D+P    -9]Q@
MY"!M  @,$ !/9C @;0 (#"@ 3@ !9@P@+?_T@;D    B8!@@;0 (#"@ 1@ !
M9@P@+?_T1H#!N0   ")2K?_\8 #_+&  _QI!55@Z4T54+P  3E4  "!Y    
M"B%\     0 D('D    *,7P  @ <0?D    ((GD    *(T@ *"\Y    "DZY
M   2(%A/3EU.=4Y5__A"K?_X2KD    J9PH(.0 "    )68*2KD    F9P !
M? @Y  0    E9UX(N0 $    )2!M  PA?/____\ #"\Y    $DZY   /HEA/
M+SD    23KD  !).6$\@>0   !9P ! H  ]R >&A+P%.N0  $D!83R\M ! O
M+0 ,3KD    $4$]@  $4"#D  P   "5G  $("+D  P   "4(.0 "    )6<(
M0KD    F8 93N0   "9*N0   "IG>BM\     ?_X(&T #"MH !C__& $4JW_
M^"!M  C1[?_X(FW__-/M__@3:/____\,*  *__]F"@@Y  (    E9QHL;0 ,
M("W_^+"N !QL#"(M__BRN0   "IMNB!M__S1[?_X#"@ "O__9Q (.0 "    
M)68&4KD    F("W_^)&Y    *B\Y    *B\M  @@;0 (T>W_^"\(3KD   \X
M3^\ # RY    _0   "IL%@@Y  4    E9PP(N0 %    )4ZZ_CX@;0 ,(6W_
M^  ,+RT $"\M  Q.N0    103TY=3G5.5?_^+SD    *3KD  !).6$\;>0  
M  C__PPM  /__V8>0BW__TJY    &F<22'@0 "\Y    &DZY   2+E!/"#D 
M @   "5F  $4$"W__TB 2,!@  #40BW__TJY    &F<22'@@ "\Y    &DZY
M   2+E!/8   YG  &T#__TB 2, CP    "I2N0   "9@  #,"#D  0   "5G
M!AM\  K__V   +@(.0 !    )6<$0BW__V   *9*N0   "IG)B!M  C1^0  
M "H,*  *__]G%%.Y    *DAX  -(>@$J3KH!+E!/0BW__V!P2KD    J9R@@
M;0 (T?D    J#"@ "O__9Q93N0   "I(>  #2'H ^DZZ /I03V#00BW__V Z
M0BW__V T68!G /\J68!GAE6 9P#_<%> 9P#_5E& 9ZI7@&>F5X!GV%. 9P#_
M*I"\    8V< _V!@R@@Y       E9RP(.0 !    )6<2#"T "O__9@I(>  -
M3KH Z%A/$"W__TB 2, O $ZZ -A83PPM  K__V8&4KD    F#+D   #^    
M*FTX"/D !0   "5*N0   "9F)@@Y  (    E9AQ2N0   "8@.0   "I2N0  
M "H@;0 ($;P "@@ 8 1.NOPV2BW__V<6(#D    J4KD    J(&T "!&M__\(
M $Y=3G4(( @ "" ( $Y5__I"K?_\0JW__& Z("W__"!M  @;< @ __L,+0 *
M__MF$@@Y  $    E9PA(>  -82)83Q M__M(@$C +P!A%%A/4JW__" M__RP
MK0 ,;;Q.74YU3E4  $HM  MG*B!Y    #B%\     0 D0>T "R)Y    #B-(
M "@O.0    Y.N0  $7)83TY=3G5.5?_T(_P    #    (DAY  $  4AX %).
MN0  $5Q03R/     "F8&< !.74YU2'D  0 !2'@ 4DZY   17%!/(\     .
M9A9(> !2+SD    *3KD  !&>4$]P &#,0J="ITZY   /S%!/('D    *(4  
M#D*G+SD    *0J=(>@$P3KD  !'J3^\ $$J 9SP@>0    HO*  .3KD  !!D
M6$](> !2+SD    .3KD  !&>4$](> !2+SD    *3KD  !&>4$]P &  _V K
M>0    K_^"MY    #O_\0JW_]& 6(&W_^%*M__@B;?_\4JW__!*04JW_] RM
M    4O_T9>!"IT*G3KD   _,4$\@>0    XA0  .('D    .,7P  P <0J="
MITZY   /S%!/(\     69V)(>  H+SD    63KD  !#04$\CP    !)G2$*G
M+SD    22'@  4AZ %Y.N0  $>I/[P 02H!F*B!Y    $C%\  D '"!Y    
M$D(H !X@>0   !)"*  ?3KKY[' !8 #^DB!Y    $D*H !1.N@"J82)P &  
M_GQS97)I86PN9&5V:6-E '1I;65R+F1E=FEC90  3E4   @Y  4    E9APO
M.0    I.N0  #Z)83R\Y    "DZY   23EA/('D    .+R@ #DZY   09%A/
M2'@ 4B\Y    #DZY   1GE!/+SD    *3KD   ^^6$\@>0    HO*  .3KD 
M !!D6$](> !2+SD    *3KD  !&>4$].74YU3E4  $JY    $F<L('D    2
M2J@ %&<.+SD    23KD   ^^6$](>  H+SD    23KD  !$:4$]*N0   !9G
M#B\Y    %DZY   09%A/3EU.=7  $"\ ![ \ &!C"K \ 'IB!) \ "!.=7  
M$"\ ![ \ $!C"K \ %IB!- \ "!.=6%\0_D    $1?D     M<EF#C(\ !=K
M"'0 (L)1R?_\(\\     +'@ !"/.    'DCG@( (+@ $ 2EG$$OZ  A.KO_B
M8 9"I_-?3G-#^@ D3J[^:"/     !&8,+CP  X '3J[_E& &3KD   #,4$].
M=61O<RYL:6)R87)Y $GY  !__DYU3.\#   $<  @+P ,L\AF DYU8Q#0P-+ 
M8 (3(%'(__Q.=1+84<C__$YU,#Q__V $,"\ #E- :Q0@;P $(F\ "+$)9@Q3
M2$H85\C_]G  3G5C!' !3G5P_TYU(&\ !" ((F\ "!#99OQ.=2)O  0L>0  
M !Y.[OX@(F\ !"QY    'D[N_BPB;P $+'D    >3N[^/DY5  !(YS@@2'C_
M_TZY   0PEA/* "PO/____]F"G  3-\$'$Y=3G5(>0 !  %(>  B3KD  !%<
M4$\D0$J 9@XO!$ZY   1MEA/< !@TB5M  @ "A5M  \ "15\  0 "$(J  X5
M1  /0J=.N0  $8I83R5  !!*K0 (9PPO"DZY   0M%A/8 Q(:@ 43KD  !'8
M6$\@"F"(3E4  $CG," D;0 (2JH "F<*+PI.N0  $A)83Q5\ /\ ""5\____
M_P 4<  0*@ /+P!.N0  $;983TAX "(O"DZY   1GE!/3-\$#$Y=3G4B;P $
M+'D    >3N[^GB O  0L>0   !Y.[OZV3E4  $CG,"!*K0 (9@IP $S?! Q.
M74YU2'D  0 !+RT #$ZY   17%!/)$!*@&8$< !@W!5\  4 "#5M  X $B5M
M  @ #B *8,9.50  2.<P("1M  @@"F8(3-\$#$Y=3G45? #_  @E?/____\ 
M%"5\_____P 8<  P*@ 2+P O"DZY   1GE!/8,Y.^0  $6),[P #  0L>0  
M !Y.[O\Z2.<# ")O  PL>0   !Y.KOXX3-\ P$YU3OD  !&0(F\ !"QY    
M'D[N_MI.^0  $:0B;P $("\ ""QY    'D[N_RX@+P $+'D    >3N[^L$[Y
M   1RB!O  0L>0   !Y.[OZ,(&\ !""(6)!"J  $(4@ "$YU(&\ !$SO @$ 
M""(O ! L>0   !Y.[OY$3.\#   $+'D    >3N[^DB)O  0L>0   !Y.[OZ8
M(F\ !"QY    'D[N_C(B;P $("\ ""QY    'D[N_KP@+P $+'D    >3N[^
MPB)O  0L>0   !Y.[OXF3OD  !)B(&\ !"QY    'D[N_H    /L     @  
M  $   ZV   /,@   $X         B    *H   "V    Z    /@   %&   !
ML    =@   'X   "(    F(   )Z   "J    M0   ,&   #*    U8   -X
M   #F@   [8   /B   $7@  !+X   3X   %7   !:8   7    &8   !Y0 
M  ?H   ']@  "!    @@   (^   "38   E,   )>@  ";    O6   +^@  
M#!H   PT   ,1   #&0   Q\   ,C@  #*    SH   -"@  #20   U$   -
MP@  #=    WB   -]   #@(   X4   .)@  #E    YB   .>   #QP   _:
M   0    $!   ! X   03   $%H  !!Z   0F   $*8  !#T   15   $5X 
M !&,   1H   $<8  !)>    E     (   %0   !5@   5P   %B   !A@  
M 9P   &\   !T@   >(   (    "&@   I(   .&   #P   !!    0V   $
M=   !-(   38   $Y@  !/(   4D   %+   !38   4^   %@   !8P   <J
M   '1   !V0   =R   '?@  !X0   >.   'J   ![(   >Z   'Q@  !]  
M  ?B   '\   !_X   @N   (.@  "$(   A*   (4@  "%@   B8   (L@  
M",P   C4   (W@  ".0   D&   )$   "1H   E&   )5   "6@   ET   )
MA   "9X   FJ   )Q@  "<P   G8   )[   "?P   H(   *%@  "C    H\
M   *2@  "J(   JL   *W@  "N@   KR   *^   "P(   L*   +$   "Q8 
M  LR   +.   "WH   NT   +Q@  "]    OJ   , @  #"(   PN   ,3   
M#%@   QR   ,B   #)H   RN   ,M@  #/    SZ   -$@  #1X   TL   -
M-@  #5(   U>   -:   #7P   VT   -O   #<H   W8   -[@  #?P   X*
M   .(   #C8   X^   .2@  #EP   YJ   .<@  #KP   [4   .W@  #P@ 
M  ^H   /M@  #\0  !"Z   0R   $6H  !%\   1E@  $:X  !&\   1T   
M$?H  !(*   2&   $B8  !(X   21@  $E0  !)H         _(   /J    
5 0 4      /R   #ZP   !@   /R
 
end
SHAR_EOF
if test 7932 -ne "`wc -c aux-handler.uue`"
then
echo shar: error transmitting aux_handler.uue '(should have been 7932 characters)'
fi
#	End of shell archive
exit 0

drew@cgou01.dec.com (Steve Drew) (05/08/87)

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	makefile
#	myaux.c
#	misc.c
# This archive created: Fri May  8 09:20:05 1987
echo shar: extracting makefile
cat << \SHAR_EOF > makefile
#########################################################################
#
#		Aux-Handler Makefile
#		V 1.0 (c) Steve Drew 1987
#		For Manx 3.40a
#
#########################################################################


aux-handler	: misc.o myaux.o
	ln  -o aux-handler misc.o myaux.o -lcl32

misc.o	: misc.c 
	cc +C +D +L +Hmyaux.syms misc.c

myaux.o	: myaux.c
	cc +C +D +L +Imyaux.syms myaux.c

SHAR_EOF
if test 401 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 401 characters)'
fi
echo shar: extracting myaux.c
cat << \SHAR_EOF > myaux.c
/****************************************************************************
 *
 *  Aux Driver V1.0 (c)CopyRight 1987, Steve Drew.  All Rights Reserved.
 *  
 *  Aux-Handler Ver. 1.0  1-May-1987
 *
 *  Steve Drew
 *  52-Castledale Cres. N.E.
 *  Calgary, Ab. Canada.
 *
 *  |You may freely distribute this source as long as |
 *  |the Copyright notice is left intact.	      |
 ***************************************************************************/


#include <devices/serial.h>
#include <devices/timer.h>


typedef unsigned char u_char;

#undef  BADDR
#define BADDR(x)   ((APTR)((long)x << 2))

#define ACTION_FINDINPUT       1005L
#define ACTION_FINDOUTPUT      1006L
#define ACTION_END	       1007L
#define ACTION_SCREEN_MODE 	994L

#define DOS_FALSE    		0L
#define DOS_TRUE     	       -1L

#define AUX_ECHO     		1
#define AUX_CRLF     		2
#define AUX_RAW      		4
#define AUX_RPEND    		8
#define AUX_WAIT_FOR 		16
#define AUX_TYPEAHEAD_FULL 	32
#define AUXBUFSIZE              256  /* Same as CON: handler */
#define MAXLINESIZE   		254  /* save two for \n'\0'  */


#define MYPORT_SIG  (1L << myport->mp_SigBit)
#define READSER_SIG (1L << ReadSER->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
#define TIMER_SIG   (1L << Timer_Port->mp_SigBit)

/* extern long AbsExecBase; */

/* My Globals */


struct	IOExtSer    *ReadSER;
struct	IOExtSer    *WriteSER;
struct  timerequest *Timer;
struct	MsgPort     *Timer_Port;
struct  Task  	    *reader;
long		    SysBase;
int		    aux_stat, 
		    aux_avail,
		    in_len;
u_char	            in_c;

_main()
{

    extern void returnpkt();		/* sends back the packet          */
    extern void returnpktplain();	/* use args in Res1               */
    extern struct DosPacket *taskwait();

    	   char       *version = 	"Ver 1.0 (c) Steve Drew 1987";
    struct Process    *myproc;     	/* my process			  */
    struct DosPacket  *mypkt;      	/* a pointer to the dos packet    */
    struct DosPacket  *rdpkt;     
    struct DeviceNode *mynode;     	/* our device node (parmpkt Arg3) */
    struct FileHandle *fh;	 	/* a pointer to our file handle	  */
    struct MsgPort    *myport;	
    long	      run = TRUE;	/* handler main loop flag	  */
    u_char            *ptr;		/* ptr for name translation       */
    char	      *name,*s;		/* ptr to name for open		  */
    int		      aux_open = 0;	/* aux open count		  */
    char	      auxbuf[AUXBUFSIZE];/* Our type ahead buffer	  */
    long	      signals;		/* signals that occurred in Wait  */

 
	/* Initializing the handler */

    myproc      = (struct Process *)FindTask(0L);
    mypkt       = taskwait(myproc);      /* Wait for my startup message */

	/* I don't need the name or extra info passed in Arg1/2 */

    mynode      	= (struct DeviceNode *)BADDR(mypkt->dp_Arg3);
    mynode->dn_Task 	= &myproc->pr_MsgPort; 
    myport 		= &myproc->pr_MsgPort;
    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2); 

    in_len = aux_avail = aux_stat = 0;
    reader = (struct Task *) 0;


	/* done initial stuff, now for some work */

    while(run) {

	if (aux_open) { /* then wait for read char or new action */

	    signals = Wait( MYPORT_SIG | READSER_SIG | TIMER_SIG );

	    if (signals & TIMER_SIG) {
	        WaitIO(Timer);
		aux_stat &= ~AUX_WAIT_FOR;
		rdpkt->dp_Res1 = DOS_FALSE;
		returnpktplain(rdpkt,myproc);
	    }
	    if ((signals & READSER_SIG) && CheckIO(ReadSER)) {
		read_ser(auxbuf);
		chk_pend(auxbuf,rdpkt,myproc);
	    }
	    if (signals & MYPORT_SIG) {
 	        mypkt = taskwait(myproc);
	    }
	    else	/* no new dospackets */
		continue;
	}
	else 		/* only port at the moment is myport */
	    mypkt = taskwait(myproc);

	switch(mypkt->dp_Type) {	/* find what action to perform */

	case ACTION_FINDINPUT:

	    if (reader) {  /* Have I already got a someone reading */
	        returnpkt(mypkt, myproc, DOS_FALSE, ERROR_OBJECT_IN_USE);
		break;
	    }

	case ACTION_FINDOUTPUT:

            /*
                I allow for multiple writers. But doesn't make sense
                to allow for mutilple readers.
            */
	    if (!aux_open)  {  /* first time here we open the devices */
		if ((aux_open = open_stuff()) == 0) {
		    returnpkt(mypkt, myproc, DOS_FALSE, ERROR_OBJECT_IN_USE);
		    break;
		}
	    }
	    else
		aux_open++;

	    /* get file name and Upper case it */
	    ptr = (u_char *)BADDR(mypkt->dp_Arg3);
	    name = AllocMem((long)*ptr + 1, MEMF_PUBLIC);
	    movmem(ptr+1, name, *ptr);
	    name[*ptr] = '\0';
	    for (s = name; *s; ++s) *s = toupper(*s);

	
	    /*
		This is a Hack to allow a bail out of a NEWCLI
		that is using the AUX. By doing say an echo >AUX:ENDCLI
		from another process the reader (being the NEWCLI) 
		will be sent a ENDCLI command.
	    */

	    if (!strcmp(name,"AUX:ENDCLI") && (aux_stat & AUX_RPEND)) {
		strcpy(rdpkt->dp_Arg2,"ENDCLI\n");
		rdpkt->dp_Res1 = 7L;
		returnpktplain(rdpkt, myproc);
		aux_stat &= ~AUX_RPEND;
	    }
	    else
	        chk_params(name);

	    FreeMem(name, (long)*ptr +1);
	    fh = (struct FileHandle  *)BADDR(mypkt->dp_Arg1);
	    fh->fh_Arg1 = DOS_TRUE;
	    fh->fh_Port = (struct MsgPort *)DOS_TRUE;

	    if (!reader && (mypkt->dp_Type == ACTION_FINDINPUT)) {
	        struct MsgPort *port;
	        
	        port = mypkt->dp_Port;
	        reader = port->mp_SigTask;
	        fh->fh_Arg1 = (long)port->mp_SigTask;
	    }

	    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
	    break;

	case ACTION_READ:

  	    rdpkt = mypkt;
	    aux_stat |= AUX_RPEND;
	    chk_pend(auxbuf,rdpkt,myproc);

	    break;

	case ACTION_WRITE:
	    
	    write_ser(mypkt->dp_Arg2,(int)mypkt->dp_Arg3);
	    mypkt->dp_Res1 = mypkt->dp_Arg3;  /* tell em we wrote them all */

	    returnpktplain(mypkt, myproc);
	    break;

	case ACTION_WAIT_CHAR:

	    /* just queue up to wait for data */

	    rdpkt = mypkt;
	    aux_stat |= AUX_WAIT_FOR;
	    Timer->tr_time.tv_secs  = 0L;
	    Timer->tr_time.tv_micro = rdpkt->dp_Arg1;
	    SendIO(Timer);
	    chk_pend(auxbuf,rdpkt,myproc);
	    break;
	    
        case ACTION_SCREEN_MODE:
        
            if (mypkt->dp_Arg1) {
                aux_stat |= AUX_RAW;
                aux_stat &= ~AUX_ECHO;
            }
            else {
                aux_stat &= ~AUX_RAW;
                aux_stat |= AUX_ECHO;
            }
            chk_pend();
	    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
            break;
           
	case ACTION_END:

	    if (--aux_open == 0) {
		run = 0;
		close_timer();
		close_ser();
	    }
	    if (mypkt->dp_Arg1 == (long)reader) reader = (struct Task *) 0;
	    returnpkt(mypkt, myproc, DOS_TRUE, mypkt->dp_Res2);
	    break;

	default:

	    returnpkt(mypkt, myproc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN);
	    break;
	}
    } /* end while */
    mynode->dn_Task = FALSE; 
}


/*
	Allows some flexibilty to control the port.
	Can dynamically change CRLF translation,
	Echo or RAW mode on/off.
*/
chk_params(str)
char *str;
{
    char *ptr, *s;
    int param, i=1;
    
    if (strncmp(str,"AUX:SET/",8)) return;
    ptr = str + 8;
    while(i) {
	for (s = ptr; *ptr && *ptr != '/'; ++ptr);
	if (*ptr == '\0') i = 0;
	*ptr = '\0';
	str = s+2;
 	if (ptr > str) {
	    switch (*s) {
	    case 'E':
		param = AUX_ECHO;
		break;
	    case 'C':
		param = AUX_CRLF;
		break;
	    case 'R':
		param = AUX_RAW;
		break;
	    default:
	    	param = 0;
		break;	 
	    }
       	    if (*str == 'O') {
		if (*(str+1) == 'N')  aux_stat |= param; 
		else 
		    if (*(str+1) == 'F') aux_stat &= ~param;
	    }
	}
	++ptr;
    }
}


/*
  Start a asynchronous Read request
*/
set_read()
{
	    /* set up for a read */
    ReadSER->IOSer.io_Length  = 1L;
    ReadSER->IOSer.io_Command = CMD_READ;
    ReadSER->IOSer.io_Data    = (APTR) &in_c;
    SendIO(ReadSER);
}

/*
  Check our buf to see if we have a line to return yet. Or if raw mode
  give 'em all we got.
*/
chk_pend(buf,pkt,proc)
char		 *buf;
struct DosPacket *pkt;
struct Process   *proc;
{
    extern void returnpktplain();
    char *p;
    int i=0;
    
    if ((in_len && (aux_stat & AUX_RAW)) || aux_avail) {
	if (aux_stat & AUX_WAIT_FOR) {
	    aux_stat &= ~AUX_WAIT_FOR;      /* clear the wait_for */
	    pkt->dp_Res1 = DOS_TRUE;
	    AbortIO(Timer);
	    WaitIO(Timer);
	    Wait (1L << Timer_Port->mp_SigBit);
	    returnpktplain(pkt,proc);
	}
	else if (aux_stat & AUX_RPEND) {
	    aux_stat &= ~AUX_RPEND;	 /* clear the pending read  */
	    if (aux_stat & AUX_RAW) { 
		aux_avail = 0;		 /* since we're sending all */
	    }
	    else 
		--aux_avail;

		/* if in_len is zero, then aux_avail must of been
		   set up to force us here to reply with Res1 = 0;
		   thus actually returning an EOF.
		*/
	    if (in_len) {		
                for (i = 1,p = (char *) pkt->dp_Arg2; 
                    ((p[i-1] = buf[i-1]) != 10 || (aux_stat & AUX_RAW)) &&
             	    i < pkt->dp_Arg3 && i < in_len; ++i) ;

		/* reader asked for less than 256 chars but no cr
		   was found. If not in raw mode then bump avail back
		   up since we still have the remaining CR terminated 
		   line in buf[].
		*/   
 		if (p[i-1] != 10 && !(aux_stat & AUX_RAW)) {
 		    ++aux_avail;
 	    	}
	    }   
	    in_len -= i;
	    movmem(buf+i,buf,in_len);
	    if (in_len < MAXLINESIZE - 1 && (aux_stat & AUX_TYPEAHEAD_FULL)) {
		aux_stat &= ~AUX_TYPEAHEAD_FULL;
		set_read();	/* start waiting for reads again */
	    }
	    pkt->dp_Res1 = (long)i;
	    returnpktplain(pkt,proc);
	}
    }
}

/*
  Only called here if there really is a character waiting to be read.
*/
read_ser(buf)
char *buf;
{
    char c;	

    WaitIO(ReadSER);
    c = in_c;

    if (c == 3) {       /* ^C typed so immediately send the signal */
    	c = 0;
    	if (reader)
            Signal(reader,SIGBREAKF_CTRL_C);
    }

    if (!(aux_stat & AUX_RAW)) switch(c) {
    case  4:		/* ^D, send the signal if not in raw mode */
	c = 0;
	if (reader)
	    Signal(reader,SIGBREAKF_CTRL_D);
	break;
    case 28:		/* ^\ so wipe out line and force EOF      */
	in_len = c = 0;
	++aux_avail;
	break;
    case 13:		/* CR convert to LF if CRLF turned on	  */
	if (aux_stat & AUX_CRLF) c = 10;
	break;
    case 10:		/* ignore these */
    	if (aux_stat & AUX_CRLF) c = 0;
    	break;
    case 8:		/* BS */
    case 127:		/* DEL */
	if (in_len && buf[in_len-1] != 10) {
	    --in_len;
	    write_ser("\010 \010",3);
	}
	c = 0;
	break;
    case 24: 		/* ^X */
    case 21:		/* ^U */
	while(in_len && buf[in_len-1] != 10) {
	    --in_len;	    
	    write_ser("\010 \010",3);
	}
	c = 0;
	break;
    case 27:		/* <ESC> */
	c = 0;
    default:
	break;
    }
    if (aux_stat & AUX_ECHO) {
	if ((aux_stat & AUX_CRLF) && c == 10) putc_ser(13);
	putc_ser(c);
    }
    if (c == 10)  ++aux_avail;  /* always done when CR received */
   	
   	/* If our buffer is full then ignore any further input. (it 
   	   will stack up in the serial.device buffer) If our buffer
   	   contains no CR's (unterminated) then add a newline. At
   	   this point the CON: driver would wait for the user to type
   	   a return while ignoring any other key strokes.
   	   In raw mode the buffer CAN be full and unterminated. Since
   	   when ever the reader asks for data we give him what ever
   	   we have so far.
   	*/   
    if (in_len >= MAXLINESIZE) {
	aux_stat |= AUX_TYPEAHEAD_FULL;
	if (!aux_avail && !(aux_stat & AUX_RAW)) { 
		++aux_avail;
		buf[in_len++] = 10;  
	}
    }
    else
    	set_read();

    if (c) buf[in_len++] = c;
}

/*
  Write 'em out one by one converting to CR LF if enabled.
*/
write_ser(buf,len)
char *buf;
int len;
{    
    int i=0;
    char c;
    
    for (i=0; i<len; i++) {
	c = buf[i];
	if (c == 10 && (aux_stat & AUX_CRLF)) putc_ser(13);
	putc_ser(c);
    }
}

/*
  Perform Synchronous write.
*/
putc_ser(c)
char c;
{
    if (c) {
	WriteSER->IOSer.io_Length = 1L;
	WriteSER->IOSer.io_Data = (APTR) &c;
	DoIO(WriteSER);
    }
}

open_stuff()
{
BYTE *c,*b;
int i;

    aux_stat = AUX_ECHO | AUX_CRLF;  /* set the default */
    if ((ReadSER = (struct IOExtSer *)
      AllocMem((long)sizeof(*ReadSER),MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
    return(0);
    if ((WriteSER = (struct IOExtSer *)
      AllocMem((long)sizeof(*WriteSER),MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
        FreeMem(ReadSER,(long)sizeof(*ReadSER));
        return(0);
    }          
    ReadSER->IOSer.io_Message.mn_ReplyPort = CreatePort(0,0);
    if (OpenDevice(SERIALNAME,NULL,ReadSER,NULL)) {
	DeletePort(ReadSER->IOSer.io_Message.mn_ReplyPort);
        FreeMem(WriteSER,(long)sizeof(*WriteSER));
	FreeMem(ReadSER,(long)sizeof(*ReadSER));
	return(0);
    }
    
    b = (BYTE *)ReadSER;
    c = (BYTE *)WriteSER;
    for (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;

    WriteSER->IOSer.io_Message.mn_ReplyPort = CreatePort(0,0);
    WriteSER->IOSer.io_Command = CMD_WRITE;

    /* Open Timer.device */
    if (Timer_Port = CreatePort (NULL, NULL)) {
        if ((Timer = CreateExtIO (Timer_Port, (long) sizeof (*Timer)))) {
            if (!(OpenDevice (TIMERNAME, UNIT_VBLANK, Timer, 0L))) {
                Timer->tr_node.io_Command = TR_ADDREQUEST;
                Timer->tr_node.io_Flags = 0;
                Timer->tr_node.io_Error = 0;
                set_read();
                return(1);
            }
        }
    }
    Timer->tr_node.io_Device = 0;
    close_timer();
    close_ser();
    return(0);

}

close_ser()
{
    if (!(aux_stat & AUX_TYPEAHEAD_FULL)) {
	AbortIO(ReadSER);
	WaitIO(ReadSER);
    }
    DeletePort(WriteSER->IOSer.io_Message.mn_ReplyPort);
    FreeMem(WriteSER,(long)sizeof(*WriteSER));
    CloseDevice(ReadSER);
    DeletePort(ReadSER->IOSer.io_Message.mn_ReplyPort);
    FreeMem(ReadSER,(long)sizeof(*ReadSER));
}

close_timer()
{

    if (Timer) {
        if (Timer->tr_node.io_Device)
	    CloseDevice (Timer);
	DeleteExtIO (Timer, (long) sizeof (*Timer));
    }
    if (Timer_Port)  DeletePort(Timer_Port);

}


SHAR_EOF
if test 13852 -ne "`wc -c myaux.c`"
then
echo shar: error transmitting myaux.c '(should have been 13852 characters)'
fi
echo shar: extracting misc.c
cat << \SHAR_EOF > misc.c
/*
 *  misc.c  - support routines - Phillip Lindsay (C) Commodore 1986
 *  You may freely distribute this source and use it for Amiga Development -
 *  as long as the Copyright notice is left intact.
 *
 * 30-SEP-86
 *
 */
#include <functions.h>
#include <stdio.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/console.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>

extern void returnpkt();

/* returnpkt() - packet support routine
 * here is the guy who sends the packet back to the sender...
 *
 * (I modeled this just like the BCPL routine [so its a little redundant] )
 */

void
returnpktplain(packet, myproc)
struct DosPacket *packet;
struct Process *myproc;
{
    returnpkt(packet, myproc, packet->dp_Res1, packet->dp_Res2);
}

void
returnpkt(packet, myproc, res1, res2)
struct DosPacket *packet;
struct Process *myproc;
ULONG  res1, res2;
{
    struct Message *mess;
    struct MsgPort *replyport;

    packet->dp_Res1          = res1;
    packet->dp_Res2          = res2;
    replyport                = packet->dp_Port;
    mess                     = packet->dp_Link;
    packet->dp_Port          = &myproc->pr_MsgPort;
    mess->mn_Node.ln_Name    = (char *) packet;
    mess->mn_Node.ln_Succ    = NULL;
    mess->mn_Node.ln_Pred    = NULL;
    PutMsg(replyport, mess);
}


/*
 * taskwait() ... Waits for a message to arrive at your port and
 *   extracts the packet address which is returned to you.
 */

struct DosPacket *
taskwait(myproc)
struct Process *myproc;
{
    struct MsgPort *myport;
    struct Message *mymess;

    myport = &myproc->pr_MsgPort;
    WaitPort(myport);
    mymess = GetMsg(myport);
    return((struct DosPacket *)mymess->mn_Node.ln_Name);
}

/* end of misc.c    */


SHAR_EOF
if test 1924 -ne "`wc -c misc.c`"
then
echo shar: error transmitting misc.c '(should have been 1924 characters)'
fi
#	End of shell archive
exit 0