1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998,2002  Steve Baker
4 
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 of the License, or (at your option) any later version.
9 
10      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Library General Public License for more details.
14 
15      You should have received a copy of the GNU Library General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 
19      For further information visit http://plib.sourceforge.net
20 
21      $Id: netMonitor.cxx 1568 2002-09-02 06:05:49Z sjbaker $
22 */
23 
24 #include "netMonitor.h"
25 
26 
27 class netMonitorChannel : public netChat
28 {
29   netMonitorServer* server ;
30   bool authorized ;
31   netBuffer buffer;
32 
33   void prompt () ;
34 
35   virtual void collectIncomingData	(const char* s, int n) ;
36   virtual void foundTerminator (void) ;
37 
38 public:
39 
40   netMonitorChannel ( netMonitorServer* server ) ;
41 
handleClose(void)42   virtual void handleClose (void)
43   {
44     ulSetError(UL_DEBUG, "%d: Client disconnected.",getHandle());
45     shouldDelete () ;
46     netChat::handleClose () ;
47     server -> active = 0 ;
48   }
49 } ;
50 
51 
52 // for now, we ignore any telnet option stuff sent to
53 // us, and we process the backspace key ourselves.
54 // gee, it would be fun to write a full-blown line-editing
55 // environment, etc...
56 
clean_line(char * line)57 static void clean_line (char* line)
58 {
59   char* dst = line ;
60   for ( char* src = line ; *src ; src ++ )
61   {
62     char ch = *src ;
63     if (ch==8 || ch==127)
64     {
65       // backspace
66       if (dst != line)
67         dst -- ;
68     }
69     else if (ch<127)
70     {
71       *dst++ = *src ;
72     }
73   }
74   *dst = 0 ;
75 }
76 
77 
netMonitorChannel(netMonitorServer * _server)78 netMonitorChannel::netMonitorChannel ( netMonitorServer* _server ) : buffer(512)
79 {
80   server = _server ;
81   setTerminator("\r\n");
82 
83   if ( server -> password && server -> password [0] != 0 )
84   {
85     authorized = false ;
86     push ("Enter password: ") ;
87   }
88   else
89   {
90     authorized = true ;
91     push ( netFormat("Connected to \"%s\"... Welcome!\r\n", server -> name ) ) ;
92     prompt();
93   }
94 }
95 
96 
prompt()97 void netMonitorChannel::prompt ()
98 {
99 	push ( server -> prompt ) ;
100 }
101 
102 
collectIncomingData(const char * s,int n)103 void netMonitorChannel::collectIncomingData	(const char* s, int n)
104 {
105   if ( !buffer.append(s,n) )
106   {
107     // denial of service.
108     push ("BCNU\r\n");
109     closeWhenDone();
110   }
111 }
112 
foundTerminator(void)113 void netMonitorChannel::foundTerminator (void)
114 {
115   char* line = buffer.getData();
116   clean_line ( line ) ;
117 
118   if (!authorized)
119   {
120     if (strcmp(line,server -> password) == 0)
121     {
122       authorized = true ;
123       push ( netFormat("Connected to \"%s\"... Welcome!\r\n",server -> name) ) ;
124       prompt () ;
125     }
126     else
127     {
128       close();
129     }
130   }
131   else if (*line == 0)
132   {
133     prompt();
134   }
135   else if (*line == 4 || strcmp(line,"exit") == 0)
136   {
137     push ("BCNU\r\n");  //Be seein' you
138     closeWhenDone();
139   }
140   else
141   {
142     if ( server -> cmdfunc )
143     {
144       server -> cmdfunc ( line ) ;
145     }
146     else
147     {
148       ulSetError(UL_DEBUG,"echo: %s",line);
149 
150       push(line);
151       push(getTerminator());
152     }
153 
154     prompt();
155   }
156   buffer.remove();
157 }
158 
159 
handleAccept(void)160 void netMonitorServer::handleAccept (void)
161 {
162   if ( !active )
163   {
164     netAddress addr ;
165     int s = accept ( &addr ) ;
166 
167     ulSetError(UL_DEBUG, "%d: Client %s:%d connected",s,addr.getHost(),addr.getPort());
168 
169     active = new netMonitorChannel ( this ) ;
170     active -> setHandle (s);
171   }
172 }
173 
174 
push(const char * s)175 bool netMonitorServer::push (const char* s)
176 {
177   if ( active )
178     return active -> push ( s ) ;
179   return false ;
180 }
181