#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #include <sys/types.h> #include <sys/time.h> #include <arpa/telnet.h> #include "struct.h" int Socket[9]; int MasterSocket; short SockState[9]={0,0,0,0,0,0,0,0}; char UserCmdLine[9][82]; char PromptLine[9][82]; char SockPos[9]; char OutPos[9]; char OutBuf[9][4096]; char Skippit[9]; int packet_init() { int ct; signal(SIGHUP,SIG_IGN); /* Don't want to die on a lost peer */ MasterSocket=Make_Socket(7658); if(MasterSocket==-1) { perror("MasterSocket"); exit(1); } printf("YAMA revision 1.15 is running\n"); ct=0; while(ct<9) { Socket[ct]= -1; ct++; } return(1); } int ReadData(ct) int ct; { unsigned char c; int e; /* printf("Read %d\n",ct);*/ while(1) { if((e=recv(Socket[ct],&c,1,0))!=1) break; if(Skippit[ct]) { Skippit[ct]--; continue; } if(c==IAC) { Skippit[ct]=2; continue; } if(c=='\r') { SockPos[ct]=0; return(1); } if(c==8 || c==127 && SockPos[ct]) { UserCmdLine[ct][--SockPos[ct]]=0; } if(c<32|| c>127) continue; if(SockPos[ct]==80) return(0); UserCmdLine[ct][SockPos[ct]++]=c; UserCmdLine[ct][SockPos[ct]]=0; } if(e==0 || (e==-1 && errno!=EWOULDBLOCK)) { return(-1); } return(0); } void PollSocket(ct) int ct; { int err; if(ct==-1) { int ct=0; err=accept(MasterSocket,NULL,NULL); if(err==-1) return; fcntl(err,F_SETFL,O_NDELAY); while(ct<9) { if(Socket[ct]== -1) break; ct++; } if(ct==9) { close(err); return; } Socket[ct]=err; OutPos[ct]=0; sock_write(ct,"Welcome to YAMA\r\n",17); SockState[ct]=1; /* Must set state before calling Do_Connection as it calls stuff */ Do_Connection(ct); SockPos[ct]=0; Skippit[ct]=0; strcpy(PromptLine[ct],"By what name shall I call you: "); return; } if(SockState[ct]==1) { flushout(ct); switch(ReadData(ct)) { case 1: Do_Net_Driver(ct,UserCmdLine[ct]);break; case -1:Do_Disconnect(ct); close(Socket[ct]); SockState[ct]= 0; Socket[ct]= -1; break; } flushout(ct); } } void Scan_Packets() { int ct= -1; struct timeval tv={1,0}; fd_set rdset,wrset; FD_ZERO(&rdset); FD_ZERO(&wrset); while(ct<9) { if(SockState[ct]==1) FD_SET(Socket[ct],&rdset); if(SockState[ct]==1 && OutPos[ct]>0) FD_SET(Socket[ct],&wrset); ct++; } FD_SET(MasterSocket,&rdset); switch(select(32,&rdset,&wrset,NULL,&tv)) { case 0: return; case -1:perror("select"); return; default: ct= -1; while(ct<9) { PollSocket(ct); ct++; } } } void WriteToHandle(int u,int c,char *t) { static char echo_off[6]={IAC,WILL,TELOPT_ECHO,IAC,WILL,TELOPT_ECHO}; static char echo_on[7]={IAC,WONT,TELOPT_ECHO,IAC,WONT,TELOPT_ECHO,'\n'}; if(SockState[u]!=1) return; switch(c) { case PK_DISC: SockState[u]=2; close(Socket[u]); Socket[u]= -1; break; case PK_PRMP: strcpy(PromptLine[u],t); break; case PK_ENAB: t=PromptLine[u]; case PK_TXLN: sock_write(u,t,strlen(t)); if(t!=PromptLine[u]) sock_write(u,"\r\n",2); break; case PK_NECH: sock_write(u,echo_off,6); break; case PK_ECHO: sock_write(u,echo_on,7); break; default:break; } } void say_to_user(int m,tag u,char *t) { WriteToHandle(VAL(u),PK_TXLN,t); } int flushout(s) { int done; if(Socket[s]==-1) return(-1); done=write(Socket[s],OutBuf[s],OutPos[s]); if(done==-1 && errno!=EWOULDBLOCK) { SockState[s]=0; close(Socket[s]); Socket[s]= -1; Do_Disconnect(s); return(-1); } OutPos[s]-=done; bcopy(OutBuf[s]+OutPos[s],OutBuf[s],OutPos[s]-done); return(OutPos[s]); } int sock_write(int s,char *buf,int n) { int sent; if(flushout(s)>0) sent=0; else { sent=write(Socket[s],buf,n); if(sent==n) return(1); } if(sent<0) sent=0; if(OutPos[s]+n-sent>4096) { Do_Disconnect(s); Socket[s]= -1; SockState[s]= 0; return(-1); } bcopy(buf+sent,OutBuf[s]+OutPos[s],n-sent); OutPos[s]+=sent; }