home *** CD-ROM | disk | FTP | other *** search
- #define CLIB_SOCKET_INLINES_H /* avoid that include file */
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/utility.h>
- #include <errno.h>
- #include <sys/ioctl.h>
- #include <exec/errors.h>
- #include <devices/serial.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <inetd.h>
-
- #include <fakesr.h>
- /*#include <libraries/multiuser.h>
- #include <proto/multiuser.h>
- */
- /* IMPORTANT: Do NOT link this module with the startup code */
-
- struct InstData {
- struct Library *DOSB;
- struct Library *SocketB;
- struct Library *UtilityB;
- int Socket;
- signed short RecvBuf[1024];
- int RecvBufPos;
- int RecvBufFlags;
- /* Defines for RecvBufFlags: */
- #define RBF_SUBNEGOTIATE (1<<0)
- };
-
- #undef DEBUG
-
- struct Library *SocketBase; /* Linker wants it. We don't use it */
- #ifndef USE_INETD
- struct Library *SysBase;
- #endif
-
- const char *Signature="FAKEMSG--EXPUNGE";
-
- #define DOSBase Inst->DOSB
- #define SocketBase Inst->SocketB
- #define UtilityBase Inst->UtilityB
- #define Socket Inst->Socket
-
- /* telnet symbols */
- #define IAC 255
- #define WILL 251
- #define WONT 252
- #define DO 253
- #define DONT 254
- #define ECHO 1
- #define LINEMODE 34
- #define SE 240
- #define SB 250
- #define MODE 1
- #define EDIT 1
-
- struct PasswdInfo {
- char Login[50];
- char Passwd[50];
- char RealName[150];
- char WorkDir[256];
- char Command[512];
- };
-
- void SockPuts(struct InstData *Inst,int Sock,char *Buf);
- void SockGets(struct InstData *Inst,int Sock,char *Buf,int BufSize);
- unsigned long GetInt(char *String,char **NewPtr);
- struct PasswdInfo *LookupPasswd(struct InstData *Inst,char *Login);
- int __asm SubSubProc(register __a0 char *ArgString,register __d0 long Length);
- struct DosPacket *PktFromMsg(struct Message *Msg);
- void MakeLongStr(char *StrBuf,unsigned long Num);
- void SockWrite(struct InstData *Inst,int Sock,char *Buf,int Len,int RawFlag);
- int RecvChar(struct InstData *Inst,int Sock,unsigned char *Loc,int RawMode);
- struct Process *MyCreateNewProcTags(struct InstData *,ULONG,...);
- void *MyAllocDosObjectTags(struct InstData *,ULONG,ULONG,...);
- void PktFPuts(struct InstData *Inst,BPTR File,char *String);
- void SockRawWrite(struct InstData *Inst,int Sock,char *Buf,int Len);
- void MySystemTags(struct Library *DSBse,char *Cmd,ULONG Tag0,...);
- void mystrcat(char *Dest,char *Cat);
- void MyFPrintf(struct InstData *Inst,BPTR File,char *Fmt,...);
-
- ULONG FakeBeginIO(void *IORequest);
- ULONG FakeAbortIO(void *IORequest);
- ULONG FakeOpen(void *IORequest);
- ULONG FakeClose(void *IORequest);
- void mymovmem(char *From,char *To,int Len);
-
- #define NewList(list) {(list)->lh_Head=(struct Node *)&(list)->lh_Tail;(list)->lh_Tail=NULL;(list)->lh_TailPred=(struct Node *)&(list)->lh_Head;}
- #define bzero(base,n) memset(base,0,n)
- #define bcopy(from,to,n) memcpy(to,from,n)
- #ifdef DEBUG
- BPTR DebugFile;
- #endif
-
- /* SubProcCode MUST be the first function in the file */
- #ifdef USE_INETD
- void main(void)
- #else
- int __asm SubProcCode(register __a0 char *ArgStr,register __d0 long Length)
- /* ArgString will look like: "[SocketID] [SigNum] [ParentTaskID]" */
- #endif
- {
- int Cnt;
- unsigned long SockID,SigID,TaskID;
- char Buf[1000],LoginBuf[50];
- BPTR BannerFile=NULL;
- struct InstData *Inst=NULL;
- struct PasswdInfo *Info=NULL;
- struct FileHandle *FH;
- struct Message *Msg,*GotMsg;
- char NoEcho[7];
- char Echo[14];
- char *ArgString;
- int OpenCount=0;
- int AmntRead;
- int HangupFlag=FALSE;
-
- ULONG SigMask;
- long yes=TRUE;
- fd_set RdSet;
- fd_set WrSet;
- struct List ReadWaitList;
- struct DosPacket *Pkt;
- int Err;
- unsigned char Chr,NumBuf[30];
- int RawMode=FALSE;
- int NextChar=-1;
- struct MsgPort *TimePort;
- struct timerequest *TimeReq;
- /*struct Library *muBase=NULL;*/
- struct DaemonMessage *InetdStartup;
- struct Process *Self;
-
-
- #ifndef USE_INETD
- SysBase=*((struct Library **)0x00000004);
- ArgString=ArgStr;
- #endif
- /*
- Echo[0]=NoEcho[0]=IAC;
- Echo[1]=WONT;
- Echo[2]=ECHO;
- NoEcho[1]=WILL;
- NoEcho[2]=ECHO;
- Echo[3]=NoEcho[3]='\0';
- */
- Echo[0]=NoEcho[0]=IAC;
- Echo[1]=WONT;
- Echo[2]=ECHO;
- Echo[3]=IAC;
- Echo[4]=DO;
- Echo[5]=LINEMODE;
- Echo[6]=IAC;
- Echo[7]=SB;
- Echo[8]=LINEMODE;
- Echo[9]=MODE;
- Echo[10]=EDIT;
- Echo[11]=IAC;
- Echo[12]=SE;
- NoEcho[1]=WILL;
- NoEcho[2]=ECHO;
- NoEcho[3]=IAC;
- NoEcho[4]=DONT;
- NoEcho[5]=LINEMODE;
- Echo[13]=NoEcho[6]='\0';
-
- #ifndef USE_INETD
- for (Cnt=0;Cnt < Length;Cnt++) {
- if (ArgStr[Cnt]!=' ' && (ArgStr[Cnt] < '0' || ArgStr[Cnt] > '9'))
- return ERROR_FILE_NOT_OBJECT;
- }
- #endif
- Inst=AllocMem(sizeof(struct InstData),MEMF_CLEAR);
- if (!Inst) return 0;
- DOSBase=OpenLibrary("dos.library",36);
- UtilityBase=OpenLibrary("utility.library",36);
- SocketBase=OpenLibrary("bsdsocket.library",2);
- /* muBase=OpenLibrary("multiuser.library",39);*/
-
-
- TimePort=CreateMsgPort();
-
- if (!DOSBase || !UtilityBase || !SocketBase || !TimePort) return 0;
- #ifdef DEBUG
- DebugFile=Open("con:0/0/500/100/TelnetGetty DEBUG/WAIT/CLOSE",MODE_OLDFILE);
- FPuts(DebugFile,"TelnetGetty starting\nArgString=");
- FPuts(DebugFile,ArgString);
- FPuts(DebugFile,"\n");
-
- #endif
-
- #ifdef USE_INETD
- Self=FindTask(NULL);
- InetdStartup=(struct DaemonMessage *)Self->pr_ExitData;
- if (!InetdStartup) goto quit;
- Socket=ObtainSocket(InetdStartup->dm_Id,InetdStartup->dm_Family,InetdStartup->dm_Type,0);
- if (Socket < 0) goto quit;
-
- #else
- /* Get arguments */
- NewList(&ReadWaitList);
- SockID=GetInt(ArgString,&ArgString);
- ArgString++; /* Skip over space */
- SigID=GetInt(ArgString,&ArgString);
- ArgString++; /* Skip over space */
- TaskID=GetInt(ArgString,&ArgString);
- /* After this call, the parameter string is no longer valid */
- Signal((struct Task *)TaskID,1<<SigID);
- #ifdef DEBUG
- FPuts(DebugFile,"Signaled parent\n");
- #endif
-
- /* We're on our own now */
- Socket=ObtainSocket(SockID,AF_INET,SOCK_STREAM,0);
- if (Socket < 0) goto quit;
-
- #endif
-
- #ifdef DEBUG
- FPuts(DebugFile,"Got Socket\n");
- #endif
- /* First, display banner, ask for password, etc */
- BannerFile=Open("tnserv:banner",MODE_OLDFILE);
- if (!BannerFile) goto quit;
- #ifdef DEBUG
- FPuts(DebugFile,"Opened tnserv:banner\n");
- #endif
- while (FGets(BannerFile,Buf,sizeof(Buf))) {
- SockWrite(Inst,Socket,Buf,strlen(Buf),FALSE);
- }
- #ifdef DEBUG
- FPuts(DebugFile,"Wrote tnserv:banner to socket\n");
- #endif
- /* Get login name */
- SockPuts(Inst,Socket,"Login: ");
- SockPuts(Inst,Socket,Echo);
- SockGets(Inst,Socket,LoginBuf,sizeof(LoginBuf));
- while (strlen(LoginBuf) && (LoginBuf[strlen(LoginBuf)-1]=='\n' || LoginBuf[strlen(LoginBuf)-1]=='\r'))
- LoginBuf[strlen(LoginBuf)-1]='\0';
- #ifdef DEBUG
- FPuts(DebugFile,"Got Login: ");
- FPuts(DebugFile,LoginBuf);
- FPuts(DebugFile,"\n");
- #endif
-
- Info=LookupPasswd(Inst,LoginBuf);
- if (!Info || strcmp(Info->Passwd,"*")) {
-
- strcpy(Buf,"Password: ");
- strcpy(Buf+strlen(Buf),NoEcho);
- SockPuts(Inst,Socket,Buf);
- SockGets(Inst,Socket,Buf,sizeof(Buf));
- while (strlen(Buf) && (Buf[strlen(Buf)-1]=='\n' || Buf[strlen(Buf)-1]=='\r'))
- Buf[strlen(Buf)-1]='\0';
- SockPuts(Inst,Socket,Echo);
- #ifdef DEBUG
- FPuts(DebugFile,"Got Password: ");
- FPuts(DebugFile,Buf);
- FPuts(DebugFile,"\n");
- #endif
- if (strcmp(Buf,Info->Passwd)) {
- SockPuts(Inst,Socket,"\nLogin incorrect.\nClosing connection\n");
- CloseSocket(Socket);
- goto quit;
- }
- }
-
-
- /*
- if (muBase) {
- struct TagItem tags[]={
- {muT_Graphical,FALSE},
- {muT_Task,NULL},
- {muT_Global,FALSE},
- /*{muT_Quiet,FALSE},*/
- /* {muT_All,FALSE}, */
- {muT_UserID,NULL},
- {muT_Password,NULL},
- {TAG_END,0}
- };
- tags[1].ti_Data=FindTask(NULL);
- tags[5].ti_Data=LoginBuf;
- tags[6].ti_Data=Buf;
- muLoginA(tags);
- }
- */
- SockPuts(Inst,Socket,"\n");
-
- if (Info->Command[0]=='*') {
- /* Use stdin/stdout */
- /* Make myself a filehandle */
- #ifdef DEBUG
- FPuts(DebugFile,"Logged in OK\nMaking Filehandle\n");
- #endif
-
- FH=MyAllocDosObjectTags(Inst,DOS_FILEHANDLE,ADO_FH_Mode,MODE_OLDFILE,TAG_END);
- if (!FH) goto quit;
- FH->fh_Pos=FH->fh_End=-1;
- FH->fh_Type=&((struct Process *)FindTask(NULL))->pr_MsgPort;
- FH->fh_Args=(LONG)Info;
- FH->fh_Port=FH->fh_Type; /* Is this right? */
- FH=(struct FileHandle *)MKBADDR(FH);
- OpenCount++;
-
- /* Run the subprocess */
- MakeLongStr(Buf,(ULONG)FH);
- strcpy(Buf+strlen(Buf)," ");
- strcpy(Buf+strlen(Buf),Info->Command+1 /* ignore the leading '*' */);
- #ifdef DEBUG
- FPuts(DebugFile,"Starting subprocess\nCmdLine=");
- FPuts(DebugFile,Buf);
- FPuts(DebugFile,"\n");
- /*Close(DebugFile);*/
- Flush(DebugFile);
-
- /*DebugFile=NULL;*/
- #endif
-
- /* NO more DOS calls allowed after this one */
- /* We also can't use Buf after we make this call */
- if (*(Info->Command+1)) {
- MyCreateNewProcTags(Inst,NP_Entry,SubSubProc,
- NP_Arguments,Buf,
- NP_Name,"Telnet subprocess",
- TAG_END);
- }
- FD_ZERO(&RdSet);
- IoctlSocket(Socket,FIONBIO,(caddr_t)&yes);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Starting handler support\n");
- #endif
- for (;;) {
- if (ReadWaitList.lh_Head->ln_Succ && !HangupFlag) {
- if (NextChar != -1) {
- Pkt=PktFromMsg((struct Message *)ReadWaitList.lh_Head);
- *(((unsigned char *)Pkt->dp_Arg2)+Pkt->dp_Res1)=NextChar;
- Chr=NextChar;
- NextChar=-1;
- Err=1;
- Pkt->dp_Res1++;
- if (Pkt->dp_Res1==Pkt->dp_Arg3 || Chr=='\r' || Chr=='\n') {
- Remove(ReadWaitList.lh_Head);
- PutMsg(Pkt->dp_Port,Pkt->dp_Link); /* Send it back */
- }
- }
- }
- if (ReadWaitList.lh_Head->ln_Succ && !HangupFlag) {
- FD_SET(Socket,&RdSet);
- } else {
- FD_CLR(Socket,&RdSet);
- }
- SigMask=(1<<((struct Process *)FindTask(NULL))->pr_MsgPort.mp_SigBit)|(1<<TimePort->mp_SigBit);
- WaitSelect(Socket+1,&RdSet,NULL,NULL,NULL,&SigMask);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Wait ended \n");
- #endif
-
- if (FD_ISSET(Socket,&RdSet)) {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got read available from socket\n");
- #endif
- if (ReadWaitList.lh_Head->ln_Succ) {
- /* Someone is waiting to read */
- Pkt=PktFromMsg((struct Message *)ReadWaitList.lh_Head);
- if (Pkt && Pkt->dp_Type==ACTION_READ) {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Performing delayed read\n");
- #endif
- while (Pkt->dp_Res1 < Pkt->dp_Arg3) {
- if (NextChar != -1) {
- *(((unsigned char *)Pkt->dp_Arg2)+Pkt->dp_Res1)=NextChar;
- Chr=NextChar;
- NextChar=-1;
- Err=1;
- } else {
- Err=RecvChar(Inst,Socket,((char *)Pkt->dp_Arg2)+Pkt->dp_Res1,FALSE/*RawMode*/);
- Chr=*(((char *)Pkt->dp_Arg2)+Pkt->dp_Res1);
- }
- if (Err==1) Pkt->dp_Res1++;
- else if (Err==0) {
- /* Hangup */
- HangupFlag=TRUE;
- break;
- } else break;
- #ifdef DEBUG
- if (Chr==255) {
- PktFPuts(Inst,DebugFile,"Received 255\n");
- }
- #endif
- if (Chr=='\r' || Chr=='\n') {
- break;
- }
- }
- if (Err==1) {
- if (Pkt->dp_Res1==Pkt->dp_Arg3 || Chr=='\r' || Chr=='\n') {
- Remove(ReadWaitList.lh_Head);
- PutMsg(Pkt->dp_Port,Pkt->dp_Link); /* Send it back */
- }
- }
- } else if (Pkt && Pkt->dp_Type==ACTION_WAIT_CHAR) {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Processing WAIT_CHAR");
- #endif
- if (NextChar==-1) {
- Err=RecvChar(Inst,Socket,&Chr,FALSE);
- if (Err==1) {
- Pkt->dp_Res1=DOSTRUE;
- Remove(ReadWaitList.lh_Head);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"char ready\n");
- #endif
- AbortIO((struct IORequest *)Pkt->dp_Res2);
- WaitIO((struct IORequest *)Pkt->dp_Res2);
- CloseDevice((struct IORequest *)Pkt->dp_Res2);
- DeleteIORequest((struct IORequest *)Pkt->dp_Res2);
- Pkt->dp_Res2=0;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- NextChar=Chr;
- } else {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"no char available\n");
- #endif
- NextChar=-1;
- }
- if (Err==0) HangupFlag=TRUE;
- } else {
- Pkt->dp_Res1=DOSTRUE;
- Remove(ReadWaitList.lh_Head);
- AbortIO((struct IORequest *)Pkt->dp_Res2);
- WaitIO((struct IORequest *)Pkt->dp_Res2);
- CloseDevice((struct IORequest *)Pkt->dp_Res2);
- DeleteIORequest((struct IORequest *)Pkt->dp_Res2);
- Pkt->dp_Res2=0;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"char ready\n");
- #endif
- }
- }
- else { /* Invalid message */
- Remove(ReadWaitList.lh_Head);
- }
- } else {
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Unexpected: got read ready, no request\n");
- #endif
- }
- }
- while (TimeReq=(struct timerequest *)GetMsg(TimePort)) {
- Msg=(struct Message *)TimeReq->tr_node.io_Message.mn_Node.ln_Name;
- Pkt=PktFromMsg(Msg);
- CloseDevice(TimeReq);
- DeleteIORequest(TimeReq);
- Pkt->dp_Res1=DOSFALSE;
- Pkt->dp_Res2=0;
- Remove(Msg); /* Remove it from the read wait list */
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
-
-
- }
- while (Msg=GetMsg(&((struct Process *)FindTask(NULL))->pr_MsgPort)) {
- Pkt=PktFromMsg(Msg);
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got packet\n");
- #endif
- switch(Pkt->dp_Type) {
- case ACTION_FINDINPUT:
- case ACTION_FINDOUTPUT:
- case ACTION_FINDUPDATE:
- FH=(struct FileHandle *)BADDR((BPTR)Pkt->dp_Arg1);
- FH->fh_Pos=FH->fh_End=-1;
- FH->fh_Type=&((struct Process *)FindTask(NULL))->pr_MsgPort;
- FH->fh_Args=(LONG)Info;
- FH->fh_Port=FH->fh_Type; /* Is this right? */
- OpenCount++;
- Pkt->dp_Res1=DOSTRUE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- break;
-
- case ACTION_READ:
- Pkt->dp_Res1=0;
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_read\n");
- #endif
- AddTail(&ReadWaitList,Msg);
- break;
-
- case ACTION_WRITE:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_write\n");
- #endif
- SockWrite(Inst,Socket,(char *)Pkt->dp_Arg2,Pkt->dp_Arg3,FALSE/*RawMode*/);
- Pkt->dp_Res1=Pkt->dp_Arg3;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- break;
-
- case ACTION_WAIT_CHAR:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_waitchar");
- #endif
- Pkt->dp_Res1=DOSFALSE;
-
- TimeReq=CreateIORequest(TimePort,sizeof(struct timerequest));
- if (!TimeReq || OpenDevice("timer.device",UNIT_MICROHZ,TimeReq,0)) {
- if (TimeReq) DeleteIORequest(TimeReq);
- Pkt->dp_Res2=ERROR_NO_FREE_STORE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- }
- TimeReq->tr_node.io_Command=TR_ADDREQUEST;
- TimeReq->tr_time.tv_micro=Pkt->dp_Arg1;
- TimeReq->tr_time.tv_secs=0;
- TimeReq->tr_node.io_Message.mn_Node.ln_Name=Msg;
- SendIO(TimeReq);
- Pkt->dp_Res2=(ULONG)TimeReq;
-
- AddTail(&ReadWaitList,Msg);
-
- break;
-
- /*
- case ACTION_DISKINFO:
-
- break;
- */
- case ACTION_SCREEN_MODE:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_screen_mode\n");
- #endif
- if (Pkt->dp_Arg1) {
- /* Raw mode */
- SockPuts(Inst,Socket,NoEcho);
- RawMode=TRUE;
- } else {
- SockPuts(Inst,Socket,Echo);
- RawMode=FALSE;
- }
- Pkt->dp_Res1=DOSFALSE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- break;
-
- case ACTION_END:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_end\n");
- #endif
- Pkt->dp_Res1=0;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- OpenCount--;
- if (!OpenCount) {
- for (GotMsg=ReadWaitList.lh_Head;GotMsg->mn_Node.ln_Succ;GotMsg=(struct Message *)GotMsg->mn_Node.ln_Succ) {
- Pkt=PktFromMsg(GotMsg);
- if (Pkt->dp_Type==ACTION_WAIT_CHAR) {
- AbortIO((struct IORequest *)Pkt->dp_Res2);
- WaitIO((struct IORequest *)Pkt->dp_Res2);
- CloseDevice((struct IORequest *)Pkt->dp_Res2);
- DeleteIORequest((struct IORequest *)Pkt->dp_Res2);
- Pkt->dp_Res2=0;
- }
- }
-
- goto quit;
- }
- break;
-
- case ACTION_SEEK:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_seek\n");
- #endif
- Pkt->dp_Res1=-1;
- Pkt->dp_Res2=ERROR_OBJECT_WRONG_TYPE;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
-
- break;
-
-
- default:
- #ifdef DEBUG
- PktFPuts(Inst,DebugFile,"Got action_not_known. Number");
- MakeLongStr(NumBuf,Pkt->dp_Type);
- PktFPuts(Inst,DebugFile,NumBuf);
- PktFPuts(Inst,DebugFile,"\n");
- #endif
- Pkt->dp_Res1=0;
- Pkt->dp_Res2=ERROR_ACTION_NOT_KNOWN;
- PutMsg(Pkt->dp_Port,Pkt->dp_Link);
- }
- }
- }
- } else {
- /* Use fake serial */
- struct IOStdReq *IOReq=NULL;
- struct MsgPort *IOPort=NULL;
- struct FSRUnit *SerUnit=NULL;
- /* SerUnit->fsru_UserData[0]=CmdPort
- SerUnit->fsru_UserData[1]=ReadQueue
- SerUnit->fsru_UserData[2]=WriteQueue
- SerUnit->fsru_UserData[3]=Open count
- SerUnit->fsru_UserData[4]=RBufLen */
- struct MsgPort *CmdPort=NULL;
- struct List *ReadQueue=NULL;
- struct List *WriteQueue=NULL;
- char *CmdPtr;
- struct IOExtSer *GotReq=NULL,*OtrReq=NULL;
- char *RBuf=NULL;
- int RBufPos=0;
- int SerUnitAdded=FALSE;
- int Amnt;
- int RecvRet;
- int CD=TRUE; /* Carrier Detect */
- long UnitNum=FSR_UNITNONE;
-
- /* We use IOExtSer.Status bit 0 as a flag to say whether this request has
- been aborted */
-
- #ifdef DEBUG
- FPuts(DebugFile,"Creating ports...\n");
- #endif
- IOPort=CreateMsgPort();
- CmdPort=CreateMsgPort();
- IOReq=CreateIORequest(IOPort,sizeof(struct IOStdReq));
- if (!IOPort || !IOReq || !CmdPort) {
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to create message port/IORequest\nExiting\n");
- #endif
- goto quitfakeser;
- }
- #ifdef DEBUG
- FPuts(DebugFile,"Opening fakesr.device...\n");
- #endif
- if (OpenDevice("fakesr.device",FSR_CTLUNIT,IOReq,0)) {
- IOReq->io_Device=NULL;
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to open fakesr.device\nExiting\n");
- #endif
- goto quitfakeser;
- }
- #ifdef DEBUG
- FPuts(DebugFile,"opened successfully\n");
- #endif
- SerUnit=AllocMem(sizeof(struct FSRUnit),MEMF_CLEAR|MEMF_PUBLIC);
- ReadQueue=AllocMem(sizeof(struct List),MEMF_PUBLIC);
- if (ReadQueue) NewList(ReadQueue);
- WriteQueue=AllocMem(sizeof(struct List),MEMF_PUBLIC);
- if (WriteQueue) NewList(WriteQueue);
- if (!SerUnit || !ReadQueue || !WriteQueue) {
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to allocate memory\nExiting\n");
- #endif
- goto quitfakeser;
- }
-
- CmdPtr=Info->Command;
- if (Info->Command[0]<='9' && Info->Command[0] >= '0') {
- UnitNum=GetInt(Info->Command,&CmdPtr);
- }
-
- SerUnit->fsru_Num=UnitNum;
- SerUnit->fsru_BeginIO=FakeBeginIO;
- SerUnit->fsru_AbortIO=FakeAbortIO;
- SerUnit->fsru_Open=FakeOpen;
- SerUnit->fsru_Close=FakeClose;
- SerUnit->fsru_UserData[0]=CmdPort;
- SerUnit->fsru_UserData[1]=ReadQueue;
- SerUnit->fsru_UserData[2]=WriteQueue;
- SerUnit->fsru_UserData[3]=0;
- SerUnit->fsru_UserData[4]=(void *)1024;
-
- IOReq->io_Data=(APTR)SerUnit;
- IOReq->io_Length=sizeof(*SerUnit);
- IOReq->io_Command=FSRCMD_ADDUNIT;
- IOReq->io_Error=0;
- #ifdef DEBUG
- FPuts(DebugFile,"Adding FakeSr unit...");
- #endif
-
- DoIO(IOReq);
- if (IOReq->io_Error) {
- #ifdef DEBUG
- FPuts(DebugFile,"Error adding fakesr.device unit\nExiting\n");
- #endif
- goto quitfakeser;
- }
-
- SerUnitAdded=TRUE;
-
- #ifdef DEBUG
- FPuts(DebugFile,"Done\n");
- #endif
-
- RBuf=AllocMem((ULONG)SerUnit->fsru_UserData[4],MEMF_PUBLIC);
- RBufPos=0;
- if (!RBuf) {
- #ifdef DEBUG
- FPuts(DebugFile,"Unable to allocate memory\nExiting\n");
- #endif
- goto quitfakeser;
- }
-
-
- IoctlSocket(Socket,FIONBIO,(caddr_t)&yes);
- {
- BPTR NilInput,NilOutput;
- #ifdef DEBUG
- FPuts(DebugFile,"Opening filehandles\n");
- #endif
- if (*CmdPtr) {
- NilInput=Open("NIL:",MODE_OLDFILE);
- NilOutput=Open("NIL:",MODE_OLDFILE);
-
- /* sprintf(Buf,"%s -DEVICE fakesr.device -UNIT %ld",CmdPtr,SerUnit->fsru_Num); */
- strcpy(Buf,CmdPtr);
- mystrcat(Buf," -DEVICE fakesr.device -UNIT ");
- MakeLongStr(LoginBuf,SerUnit->fsru_Num);
- #ifdef DEBUG
- FPuts(DebugFile,"Got FakeSr unit: ");
- FPuts(DebugFile,LoginBuf);
- FPuts(DebugFile,"\n");
- #endif
- SockPuts(Inst,Socket,NoEcho);
-
- mystrcat(Buf,LoginBuf);
- #ifdef DEBUG
- FPuts(DebugFile,"Running command:");
- FPuts(DebugFile,Buf);
- FPuts(DebugFile,"\n");
- #endif
- MySystemTags(DOSBase,Buf,SYS_Input,NilInput,SYS_Output,NilOutput,SYS_Asynch,TRUE,TAG_END);
- }
- }
-
- for (;;) {
- FD_ZERO(&RdSet);
- FD_ZERO(&WrSet);
- if (CD) {
- if (RBufPos < (((long)SerUnit->fsru_UserData[4])-1)) FD_SET(Socket,&RdSet);
- if (WriteQueue->lh_Head->ln_Succ) FD_SET(Socket,&WrSet);
- }
- SigMask=(1<<CmdPort->mp_SigBit)|SIGBREAKF_CTRL_C;
- WaitSelect(Socket+1,&RdSet,&WrSet,NULL,NULL,&SigMask);
- #ifdef DEBUG
- FPuts(DebugFile,"Wait ended...");
- #endif
-
- if (FD_ISSET(Socket,&RdSet)) {
- while ((RBufPos < (long)SerUnit->fsru_UserData[4]) && ((RecvRet=RecvChar(Inst,Socket,RBuf+RBufPos,TRUE))==1)) RBufPos++;
- Forbid();
- if ((GotReq=(struct IOExtSer *)ReadQueue->lh_Head)->IOSer.io_Message.mn_Node.ln_Succ) {
- Remove(GotReq);
- Permit();
- Amnt=min(RBufPos,GotReq->IOSer.io_Length);
- memcpy(((char *)GotReq->IOSer.io_Data)+GotReq->IOSer.io_Actual,RBuf,Amnt);
- GotReq->IOSer.io_Actual+=Amnt;
- if (Amnt < RBufPos) mymovmem(RBuf+Amnt,RBuf,RBufPos-Amnt);
- RBufPos-=Amnt;
-
- if (GotReq->IOSer.io_Actual < GotReq->IOSer.io_Length) {
- if (GotReq->io_Status & (1<<0)) {
- /* We got an AbortIO() */
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(GotReq);
- } else {
- Forbid();
- AddTail(ReadQueue,GotReq);
- Permit();
- }
- }
- else ReplyMsg(GotReq);
-
- }
- else Permit();
- if (RecvRet==0) {
- /* Connection closed */
- CD=FALSE;
- }
- }
- if (FD_ISSET(Socket,&WrSet)) {
- Forbid();
- if ((GotReq=(struct IOExtSer *)WriteQueue->lh_Head)->IOSer.io_Message.mn_Node.ln_Succ) {
- Remove(GotReq);
- Permit();
-
- #ifdef DEBUG
- FPuts(DebugFile,"Writing to socket\n");
- MyFPrintf(Inst,DebugFile,"io_Actual=%ld,io_Length=%ld\n",(long)GotReq->IOSer.io_Actual,(long)GotReq->IOSer.io_Length);
- #endif
- SockWrite(Inst,Socket,((char *)GotReq->IOSer.io_Data)+GotReq->IOSer.io_Actual,GotReq->IOSer.io_Length-GotReq->IOSer.io_Actual,TRUE);
- #ifdef DEBUG
- FPuts(DebugFile,"Write completed\n");
- #endif
- GotReq->IOSer.io_Actual=GotReq->IOSer.io_Length;
-
-
- if (GotReq->IOSer.io_Actual < GotReq->IOSer.io_Length) {
- Forbid();
- if (GotReq->io_Status & (1<<0)) {
- Permit();
- /* We got an AbortIO() */
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(GotReq);
- } else {
- AddTail(WriteQueue,GotReq);
- Permit();
- }
- } else {
- #ifdef DEBUG
- FPuts(DebugFile,"Replying write message\n");
- #endif
- ReplyMsg(GotReq);
- }
-
-
- } else {
-
- Permit();
- }
- }
- while (GotReq=(struct IOExtSer *)GetMsg(CmdPort)) {
- if (GotReq->IOSer.io_Message.mn_Node.ln_Name==Signature) {
- /* We just use the pointer as a signature */
- /* We just got an expunge request */
- #ifdef DEBUG
- FPuts(DebugFile,"Got expunge request\n");
- #endif
-
- FreeMem(GotReq,sizeof(struct Message)); /* We free the expunge request instead of reply */
-
- Forbid();
- if (SerUnit->fsru_UserData[3]==0) {
- /* Open count==0 */
- if (SerUnitAdded) {
- IOReq->io_Command=FSRCMD_REMUNIT;
- IOReq->io_Data=(APTR)SerUnit;
- IOReq->io_Length=sizeof(*SerUnit);
- DoIO(IOReq);
- SerUnitAdded=FALSE;
- }
- if (SerUnit->fsru_UserData[3]==0) {
- /* If opencnt is still 0 */
- Permit();
- goto quitfakeser; /* exit */
- }
- }
- Permit();
- }
- else {
- #ifdef DEBUG
- FPuts(DebugFile,"Got cmd...");
- #endif
-
- switch(GotReq->IOSer.io_Command) {
- case CMD_CLEAR:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_CLEAR\n");
- #endif
- RBufPos=0;
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_FLUSH:
- case CMD_RESET:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_FLUSH/RESET\n");
- #endif
-
- Forbid();
- while (OtrReq=(struct IOExtSer *)RemHead(ReadQueue)) {
- OtrReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(OtrReq);
- }
- while (OtrReq=(struct IOExtSer *)RemHead(WriteQueue)) {
- OtrReq->IOSer.io_Error=IOERR_ABORTED;
- ReplyMsg(OtrReq);
- }
- Permit();
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_READ:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_READ\n");
- #endif
-
- GotReq->IOSer.io_Actual=0;
- GotReq->IOSer.io_Error=0;
- Amnt=min(RBufPos,GotReq->IOSer.io_Length);
- memcpy(((char *)GotReq->IOSer.io_Data)+GotReq->IOSer.io_Actual,RBuf,Amnt);
- GotReq->IOSer.io_Actual+=Amnt;
- if (Amnt < RBufPos) mymovmem(RBuf+Amnt,RBuf,Amnt);
- RBufPos-=Amnt;
-
- if (GotReq->IOSer.io_Actual < GotReq->IOSer.io_Length) {
- Forbid();
- AddTail(ReadQueue,GotReq);
- Permit();
- }
- else ReplyMsg(GotReq);
- break;
-
- case CMD_START:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_START\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_STOP:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_STOP\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case CMD_WRITE:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_WRITE\n");
- #endif
-
- GotReq->IOSer.io_Actual=0;
- GotReq->IOSer.io_Error=0;
- Forbid();
- AddTail(WriteQueue,GotReq);
- Permit();
- break;
-
- case SDCMD_BREAK:
- #ifdef DEBUG
- FPuts(DebugFile,"Got SDCMD_BREAK\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- case SDCMD_QUERY:
- #ifdef DEBUG
- FPuts(DebugFile,"Got SDCMD_QUERY\n");
- #endif
-
- GotReq->IOSer.io_Actual=RBufPos;
- GotReq->io_Status=0x0000 | ((CD) ? 0:(1<<5));
- GotReq->IOSer.io_Error=0;
-
- ReplyMsg(GotReq);
- break;
-
- case SDCMD_SETPARAMS:
- #ifdef DEBUG
- FPuts(DebugFile,"Got SDCMD_SETPARAMS\n");
- #endif
-
- GotReq->IOSer.io_Error=0;
- ReplyMsg(GotReq);
- break;
-
- default:
- #ifdef DEBUG
- FPuts(DebugFile,"Got CMD_UNKNOWN\n");
- #endif
- GotReq->IOSer.io_Error=IOERR_NOCMD;
- ReplyMsg(GotReq);
-
- }
- }
- }
- }
-
-
- quitfakeser:
-
- if (ReadQueue) {
- Forbid();
- while (GotReq=(struct IOExtSer *)RemHead(ReadQueue)) {
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- GotReq->IOSer.io_Actual=0;
- ReplyMsg(GotReq);
- }
- Permit();
- FreeMem(ReadQueue,sizeof(struct List));
- }
- if (WriteQueue) {
- Forbid();
- while (GotReq=(struct IOExtSer *)RemHead(WriteQueue)) {
- GotReq->IOSer.io_Error=IOERR_ABORTED;
- GotReq->IOSer.io_Actual=0;
- ReplyMsg(GotReq);
- }
- Permit();
- FreeMem(WriteQueue,sizeof(struct List));
- }
- if (RBuf && SerUnit) {
- FreeMem(RBuf,(long)SerUnit->fsru_UserData[4]);
- }
- if (SerUnit) {
- if (SerUnitAdded && IOReq) {
- IOReq->io_Data=(APTR)SerUnit;
- IOReq->io_Length=sizeof(*SerUnit);
- IOReq->io_Command=FSRCMD_REMUNIT;
- DoIO(IOReq);
- }
- FreeMem(SerUnit,sizeof(struct FSRUnit));
- }
- if (IOReq) {
- if (IOReq->io_Device) CloseDevice(IOReq);
- DeleteIORequest(IOReq);
- }
- if (IOPort) DeleteMsgPort(IOPort);
- if (CmdPort) DeleteMsgPort(CmdPort);
- goto quit;
- }
-
- quit:
- #ifdef DEBUG
- if (DebugFile) Close(DebugFile);
- #endif
- if (TimePort) DeleteMsgPort(TimePort);
- if (Info) FreeMem(Info,sizeof(struct PasswdInfo));
- if (BannerFile) Close(BannerFile);
- if (Inst) {
- if (SocketBase) CloseLibrary(SocketBase);
- if (UtilityBase) CloseLibrary(UtilityBase);
- if (DOSBase) CloseLibrary(DOSBase);
- }
- return 0;
- }
-
- void MyFPrintf(struct InstData *Inst,BPTR File,char *Fmt,...)
- {
- VFPrintf(File,Fmt,(&Fmt)+1);
- }
-
- void mystrcat(char *Dest,char *Cat)
- {
- memcpy(Dest+strlen(Dest),Cat,strlen(Cat)+1);
- }
-
- void mymovmem(char *From,char *To,int Len)
- {
- int Cnt;
- if (From > To) {
- for (Cnt=0;Cnt < Len;Cnt++) {
- To[Cnt]=From[Cnt];
- }
- } else if (From < To) {
- for (Cnt=Len-1;Cnt >= 0;Cnt--) {
- To[Cnt]=From[Cnt];
- }
- }
- }
-
- struct Node *FindNode(struct List *List,struct Node *Node)
- /* returns Node if Node is a member of list, NULL otherwise */
- {
- struct Node *ChkNode;
-
- for (ChkNode=List->lh_Head;ChkNode->ln_Succ;ChkNode=ChkNode->ln_Succ) {
- if (ChkNode==Node) return Node;
- }
- return NULL;
- }
-
- ULONG FakeBeginIO(void *IORequest)
- {
- ((struct IORequest *)IORequest)->io_Flags &= ~IOF_QUICK; /* Quick IO not supported */
- ((struct IOExtSer *)IORequest)->io_Status &= ~(1<<0); /* clear abort bit */
- ((struct Node *)IORequest)->ln_Name=NULL; /* clear possible signature */
- PutMsg((struct MsgPort *)((struct FSRUnit *)((struct IORequest *)IORequest)->io_Unit)->fsru_UserData[0],IORequest);
- return 0;
- }
-
- ULONG FakeAbortIO(void *IORequest)
- {
- struct IOExtSer *Ser;
-
- Ser=IORequest;
- Forbid();
- Ser->io_Status |= (1<<0); /* Flag the request as aborted */
- if (FindNode(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[1],Ser) ||
- FindNode(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[2],Ser)) {
- /* This IORequest is waiting to be processed */
- Remove(Ser);
- Ser->IOSer.io_Error=IOERR_ABORTED;
- Ser->IOSer.io_Actual=0;
- ReplyMsg(Ser);
- }
- else {
- /* This IORequest is currently being processed -- send a break */
- Signal(((struct MsgPort *)((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[0])->mp_SigTask,SIGBREAKF_CTRL_C);
- }
- Permit();
-
- return 0;
- }
-
- ULONG FakeOpen(void *IORequest)
- {
- struct IOExtSer *Ser;
-
- Ser=IORequest;
- Forbid();
- ((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3]=(void *) ((long)(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3])+1); /* Increment opencnt */
- Permit();
- Ser->IOSer.io_Error=0;
- Ser->io_CtlChar=SER_DEFAULT_CTLCHAR;
- Ser->io_RBufLen=(long)((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[4];
- Ser->io_ExtFlags=0;
- Ser->io_Baud=19200;
- Ser->io_BrkTime=250000;
- Ser->io_TermArray.TermArray0=0;
- Ser->io_TermArray.TermArray1=0;
- Ser->io_ReadLen=8;
- Ser->io_WriteLen=8;
- Ser->io_StopBits=1;
- Ser->io_Status=0;
- return 0;
- }
-
- ULONG FakeClose(void *IORequest)
- {
- struct IOExtSer *Ser;
- struct Message *Msg;
-
- Ser=IORequest;
- Forbid();
-
- ((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3]=(void *) ((long)(((struct FSRUnit *)Ser->IOSer.io_Unit)->fsru_UserData[3])-1); /* Decrement opencnt */
- Msg=AllocMem(sizeof(struct Message),MEMF_PUBLIC|MEMF_CLEAR);
- Msg->mn_Node.ln_Name=Signature;
- PutMsg((struct MsgPort *)((struct FSRUnit *)((struct IORequest *)IORequest)->io_Unit)->fsru_UserData[0],Msg);
-
- Permit();
- return 0;
- }
-
-
- struct DosPacket *PktFromMsg(struct Message *Msg)
- {
- return (struct DosPacket *)Msg->mn_Node.ln_Name;
- }
-
- void PktFPuts(struct InstData *Inst,BPTR File,char *String)
- {
- struct MsgPort *ReplyPort;
- struct DosPacket *Pkt;
-
- ReplyPort=CreateMsgPort();
- Pkt=AllocDosObject(DOS_STDPKT,NULL);
- if (!Pkt || !ReplyPort) return;
-
- Pkt->dp_Type=ACTION_WRITE;
- Pkt->dp_Arg1=((struct FileHandle *)BADDR(File))->fh_Arg1;
- Pkt->dp_Arg2=String;
- Pkt->dp_Arg3=strlen(String);
- Pkt->dp_Port=ReplyPort;
- PutMsg(((struct FileHandle *)BADDR(File))->fh_Type,Pkt->dp_Link);
- WaitPort(ReplyPort);
- GetMsg(ReplyPort);
- DeleteMsgPort(ReplyPort);
- FreeDosObject(DOS_STDPKT,Pkt);
- }
-
- unsigned long GetInt(char *String,char **NewPtr)
- {
- unsigned long Num=0;
- char *Junk;
- long Cnt;
- long BaseNum;
-
- if (!NewPtr) NewPtr=&Junk;
-
- for (*NewPtr=String;;(*NewPtr)++) {
-
- if (**NewPtr < '0' || **NewPtr > '9') return Num;
-
- /* AAARGH!! multiplication causes a lib call to be generated.
- We can't use the library. Therefore we have to add */
- /* Num=Num*10; */
- for (BaseNum=Num,Cnt=0;Cnt < 9;Cnt++,Num+=BaseNum);
-
-
- Num+=**NewPtr-'0';
- }
-
- }
-
-
- void SockPuts(struct InstData *Inst,int Sock,char *Buf)
- {
- int BufPos=0;
- int BytesWritten;
-
- do {
- BytesWritten=send(Sock,Buf+BufPos,strlen(Buf+BufPos),0);
- if (BytesWritten > 0) BufPos+=BytesWritten;
- } while (Buf[BufPos]);
- }
-
- void SockRawWrite(struct InstData *Inst,int Sock,char *Buf,int Len)
- {
- int BufPos=0;
- int BytesWritten;
-
- if (!Len) return;
-
- do {
- BytesWritten=send(Sock,Buf+BufPos,Len-BufPos,0);
- if (BytesWritten > 0) BufPos+=BytesWritten;
- } while (Len-BufPos);
-
- }
-
- void SockWrite(struct InstData *Inst,int Sock,char *Buf,int Len,int RawFlag)
- {
- int Cnt;
- int BufPos=0;
- char iac2[2];
- char eol[2];
- char csi[2];
- iac2[0]=iac2[1]=IAC;
- eol[0]='\r';
- eol[1]='\n';
- csi[0]='\x1b';
- csi[1]='[';
-
-
- while (Len > BufPos) {
- for (Cnt=BufPos;Cnt < Len;Cnt++) {
- if (!RawFlag)
- if (Buf[Cnt]=='\r' || Buf[Cnt]=='\n') break;
- if (Buf[Cnt]=='\x9b') break;
- if (Buf[Cnt]==IAC) {
- break;
- }
- }
- SockRawWrite(Inst,Sock,Buf+BufPos,Cnt-BufPos);
- BufPos=Cnt;
- if (BufPos < Len && Buf[BufPos]==IAC) { /* If we got single IAC, send double IAC */
- BufPos++;
- SockRawWrite(Inst,Sock,iac2,2);
- }
- if (!RawFlag) {
- if (BufPos < Len && Buf[BufPos]=='\r') {
- BufPos++;
- }
- if (BufPos < Len && Buf[BufPos]=='\n') {
- BufPos++;
- SockRawWrite(Inst,Sock,eol,2);
- }
- if (BufPos < Len && Buf[BufPos]=='\x9b') {
- BufPos++;
- SockRawWrite(Inst,Sock,csi,2);
- }
- }
- }
- }
-
- void ParseBuf3(struct InstData *Inst)
- /* Parse 3 character remote request */
- {
-
- }
-
- void ParseBuf2(struct InstData *Inst)
- /* Parse 2 character remote-request */
- {
-
- }
-
- void ParseBufSubNegotiate(struct InstData *Inst)
- {
-
- }
-
- int RecvChar(struct InstData *Inst,int Sock,unsigned char *Loc,int RawMode)
- {
- int GotLen;
- unsigned char Got,TrueGot;
- /*RawMode=TRUE;*/
- static unsigned char PrevChar;
-
- do {
-
- GotLen=recv(Sock,&Got,1,0); /* Wait for a character */
- if (GotLen==-1) {
- if (Errno()==EINTR) continue;
- else return -1;
- } else if (GotLen==0) return 0;
-
- TrueGot=Got;
- if (!Inst->RecvBufPos && GotLen==1 && Got==0) GotLen=-1; /* Read again */
- if (GotLen==1 && !RawMode && !Inst->RecvBufPos) {
- /* These next few lines ignore incoming newlines and convert
- incoming CRs into newlines */
- if (Got=='\n' && PrevChar=='\r') GotLen=-1; /* Read again. */
- if (Got=='\r') Got='\n';
- }
- } while (GotLen != 1);
- /* *Loc=Got;
- return 1; */
-
- if (Inst->RecvBufPos) {
- Inst->RecvBuf[Inst->RecvBufPos]=Got;
- Inst->RecvBufPos++;
- switch (Inst->RecvBufPos) {
- case 2:
- switch(Inst->RecvBuf[1]) {
- case IAC:
- /* Just a single IAC */
- *Loc=IAC;
- return 1;
- break;
-
- case SB:
- Inst->RecvBufFlags|=RBF_SUBNEGOTIATE;
- return RecvChar(Inst,Sock,Loc,RawMode);
- break;
-
- case SE:
- Inst->RecvBufPos=0;
- Inst->RecvBufFlags &= ~RBF_SUBNEGOTIATE;
- return RecvChar(Inst,Sock,Loc,RawMode);
-
- case WILL:
- case WONT:
- case DO:
- case DONT:
- return RecvChar(Inst,Sock,Loc,RawMode);
- break;
-
- default:
- ParseBuf2(Inst);
- Inst->RecvBufPos=0;
- return RecvChar(Inst,Sock,Loc,RawMode);
- }
- break;
-
- default:
- if (Inst->RecvBufFlags & RBF_SUBNEGOTIATE) {
- if (Inst->RecvBufPos >= 2 && Inst->RecvBuf[Inst->RecvBufPos-2]==IAC && Inst->RecvBuf[Inst->RecvBufPos-1]!=IAC) {
- /* End of subnegotiation */
- Inst->RecvBuf[0]=IAC;
- if ((Inst->RecvBuf[1]=Inst->RecvBuf[Inst->RecvBufPos-1])==SE) {
- Inst->RecvBufFlags &= ~RBF_SUBNEGOTIATE;
- Inst->RecvBufPos=0;
- return RecvChar(Inst,Sock,Loc,RawMode);
- }
- Inst->RecvBufPos=2;
-
- ParseBufSubNegotiate(Inst);
- }
-
- if (Inst->RecvBufPos >= 2 && Inst->RecvBuf[Inst->RecvBufPos-2]==IAC && Inst->RecvBuf[Inst->RecvBufPos-1]==IAC) {
- /* We just got a double IAC in subnegotiation */
- Inst->RecvBuf[Inst->RecvBufPos-2]=-1; /* We store IAC as a (int)-1 */
- Inst->RecvBufPos--;
- }
- return RecvChar(Inst,Sock,Loc,RawMode);
- } else {
- if (Inst->RecvBuf[2]==IAC) {
- /* Restart sequence */
- Inst->RecvBuf[0]=IAC;
- Inst->RecvBufPos=1;
- return RecvChar(Inst,Sock,Loc,RawMode);
- } else {
- ParseBuf3(Inst);
- Inst->RecvBufPos=0;
- return RecvChar(Inst,Sock,Loc,RawMode);
- }
- }
- break;
- }
- }
- else {
- if (Got==IAC) {
- Inst->RecvBuf[0]=Got;
- Inst->RecvBufPos=1;
- return RecvChar(Inst,Sock,Loc,RawMode);
- } else {
- *Loc=Got;
- PrevChar=TrueGot;
- return 1;
- }
- }
- return 1;
-
- }
-
-
- void SockGets(struct InstData *Inst,int Sock,char *Buf,int BufSize)
- /* This function gets the next string until a CR
- on the specified socket, and places it in buf. It
- discards leading crs/lfs */
- {
- int BufPos=0;
- int BytesRead;
- int FirstBytes=TRUE;
- Buf[0]='\0';
-
- do {
- BytesRead=RecvChar(Inst,Sock,Buf+BufPos,FALSE);
- if (BytesRead < 0) {
- if (Errno()!=EINTR) {
- Buf[BufPos]='\0';
- return;
- }
- }
- else if (BytesRead==0) {
- Buf[BufPos]='\0';
- return;
- }
- else {
- if ((Buf[BufPos]=='\r' || Buf[BufPos]=='\n') && FirstBytes) {
- Buf[BufPos]='\0';
- } else {
- FirstBytes=FALSE;
- BufPos+=BytesRead;
- }
- }
- } while (Buf[BufPos-1] != '\r' && Buf[BufPos-1] != '\n' && BufPos < (BufSize-1));
- Buf[BufPos]='\0';
- }
-
- char *PullPasswdString(char **StringPtr)
- {
- int Cnt;
- char *RetVal;
- char *CurPos;
-
- if (!StringPtr || !*StringPtr) return NULL;
-
- RetVal=*StringPtr;
-
- for (CurPos=RetVal;*CurPos != ',' && *CurPos != '\r' && *CurPos != '\n' && *CurPos;CurPos++);
- switch (*CurPos) {
- case ',':
- case '\r':
- case '\n':
- *CurPos='\0';
- CurPos++;
- *StringPtr=CurPos;
- return RetVal;
-
- case '\0':
- *StringPtr=CurPos;
- return RetVal;
- }
- }
-
- int mystrcmp(char *S1,char *S2)
- {
- int Cnt;
- for (Cnt=0;S1[Cnt] && S2[Cnt];Cnt++) {
- if (S1[Cnt] != S2[Cnt]) return !0;
- }
- if (S1[Cnt] != S2[Cnt]) return !0;
- return 0;
- }
-
- struct PasswdInfo *LookupPasswd(struct InstData *Inst,char *Login)
- {
- BPTR File;
- char *LineBuf;
- char *BufPtr;
- char *PasswdPtr;
- char *LoginPtr;
- char *RealNamePtr;
- char *HomeDirPtr;
- char *CmdPtr;
- struct PasswdInfo *Info;
- /* int NoPasswd=FALSE; */
-
- LineBuf=AllocMem(1000,MEMF_PUBLIC);
- if (!LineBuf) return NULL;
-
- File=Open("tnserv:Passwd",MODE_OLDFILE);
- if (!File) return NULL;
-
-
- while (FGets(File,LineBuf,1000)) {
- if (LineBuf[0]=='#') continue;
- BufPtr=LineBuf;
- LoginPtr=PullPasswdString(&BufPtr);
- #ifdef DEBUG
- FPuts(DebugFile,"Got username: ");
- FPuts(DebugFile,LoginPtr);
- FPuts(DebugFile,"\n");
- #endif
- PasswdPtr=PullPasswdString(&BufPtr);
- #ifdef DEBUG
- FPuts(DebugFile,"Got password: ");
- FPuts(DebugFile,PasswdPtr);
- FPuts(DebugFile,"\n");
- #endif
- PullPasswdString(&BufPtr); /* throw away user id */
- PullPasswdString(&BufPtr); /* Throw away group id */
- RealNamePtr=PullPasswdString(&BufPtr);
- HomeDirPtr=PullPasswdString(&BufPtr);
- CmdPtr=PullPasswdString(&BufPtr);
-
- /* if (!mystrcmp(PasswdPtr,"*")) NoPasswd=TRUE;*//*strcpy(Passwd,PasswdPtr);*/
- /* else NoPasswd=FALSE; */
- if (!mystrcmp(Login,LoginPtr)) {
- #ifdef DEBUG
- FPuts(DebugFile,"Password located\n");
- #endif
- /* Password located and correct */
- /*if (CmdPtr[0]=='*') */ /* We only support stdin/out logins */
- Close(File);
- Info=AllocMem(sizeof(struct PasswdInfo),MEMF_PUBLIC);
- if (!Info) return NULL;
- strcpy(Info->Login,LoginPtr);
- strcpy(Info->Passwd,PasswdPtr);
- strcpy(Info->RealName,RealNamePtr);
- strcpy(Info->WorkDir,HomeDirPtr);
- strcpy(Info->Command,CmdPtr);
- FreeMem(LineBuf,1000);
- return Info;
- }
- }
- Close(File);
- FreeMem(LineBuf,1000);
- return NULL; /* Login failed */
- }
-
- void __asm PutMLSChar(register __d0 char Chr,register __a3 char **BufPtr)
- {
- **BufPtr=Chr;
- (*BufPtr)++;
- }
-
- void MakeLongStr(char *StrBuf,unsigned long Num)
- {
- RawDoFmt("%lu",&Num,PutMLSChar,&StrBuf);
- }
-
-
- struct Process *MyCreateNewProcTags(struct InstData *Inst,ULONG Tag1,...)
- {
- return CreateNewProc((struct TagItem *)&Tag1);
- }
-
- void *MyAllocDosObjectTags(struct InstData *Inst,ULONG Type,ULONG Tag1,...)
- {
- return AllocDosObject(Type,(struct TagItem *)&Tag1);
- }
- void MySystemTags(struct Library *DSBse,char *Cmd,ULONG Tag0,...)
- {
- #define DOSBase DSBse
- SystemTagList(Cmd,(struct TagItem *)&Tag0);
- #undef DOSBase
- }
-
- #define DOSBase DSBse
- int __asm SubSubProc(register __a0 char *ArgString,register __d0 long Length)
- {
- char StringBuf[1000];
- char *StringPtr;
- BPTR FH;
- struct Library *DSBse;
-
- DSBse=OpenLibrary("dos.library",36);
- if (!DSBse) return 0;
-
- FH=(BPTR)GetInt(ArgString,&StringPtr);
-
- /* if (IsInteractive(FH)) {
- Write(FH,"Interactive\n",12);
- }*/
- strcpy(StringBuf,StringPtr);
- if (!StringBuf[0]) {
- MySystemTags(DSBse,"execute s:remote-startup",
- SYS_Input,FH,
- SYS_Output,FH,
- NP_ConsoleTask,((struct FileHandle *)BADDR(FH))->fh_Type,
- TAG_END);
- } else {
- MySystemTags(DSBse,StringBuf,
- SYS_Input,FH,
- SYS_Output,FH,
- NP_ConsoleTask,((struct FileHandle *)BADDR(FH))->fh_Type,
- TAG_END);
- }
-
- Forbid();
- Close(FH);
- return 0;
- }
- #undef DOSBase
-