1 /******************************************************************************
2     (c) 2001-2008 Christine Caulfield                 christine.caulfield@googlemail.com
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 ******************************************************************************/
14 
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <stdio.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <termios.h>
21 #include <string.h>
22 #include <list>
23 #include <cassert>
24 #include <queue>
25 #include <string>
26 #include <map>
27 #include <sstream>
28 
29 #include "lat.h"
30 #include "utils.h"
31 #include "session.h"
32 #include "localport.h"
33 #include "connection.h"
34 #include "circuit.h"
35 #include "latcpcircuit.h"
36 #include "server.h"
37 #include "clientsession.h"
38 #include "lat_messages.h"
39 
ClientSession(class LATConnection & p,unsigned char remid,unsigned char localid,char * ttyname,bool clean)40 ClientSession::ClientSession(class LATConnection &p,
41 			     unsigned char remid, unsigned char localid,
42 			     char *ttyname, bool clean):
43   LATSession(p, remid, localid, clean),
44   slave_fd_open(false)
45 {
46     debuglog(("new client session: localid %d, remote id %d\n",
47 	    localid, remid));
48     if (ttyname) strcpy(ltaname, ttyname);
49 }
50 
51 // This should never be called now as it is overridden
52 // by all self-respecting superclasses.
new_session(unsigned char * _remote_node,char * service,char * port,unsigned char c)53 int ClientSession::new_session(unsigned char *_remote_node,
54 			       char *service, char *port,
55 			       unsigned char c)
56 {
57 
58     assert(!"Should never get here!!");
59     return 0;
60 }
61 
connect_parent()62 int ClientSession::connect_parent()
63 {
64     debuglog(("connecting parent for %s\n", ltaname));
65     return parent.connect(this);
66 }
67 
68 // Disconnect the local PTY
restart_pty()69 void ClientSession::restart_pty()
70 {
71     assert(!"ClientSession::restart_pty()\n");
72 }
73 
74 
75 // Remote end disconnects or EOF on local PTY
disconnect_session(int reason)76 void ClientSession::disconnect_session(int reason)
77 {
78     debuglog(("ClientSession::disconnect_session()\n"));
79     // If the reason was some sort of error then send it to
80     // the PTY
81     if (reason > 1)
82     {
83 	const char *msg = lat_messages::session_disconnect_msg(reason);
84 	write(master_fd, msg, strlen(msg));
85 	write(master_fd, "\n", 1);
86     }
87     LATServer::Instance()->set_fd_state(master_fd, true);
88     connected = false;
89     restart_pty();
90     return;
91 }
92 
93 
~ClientSession()94 ClientSession::~ClientSession()
95 {
96     if (slave_fd_open) close (slave_fd);
97     if (master_fd > -1)
98     {
99 	close (master_fd);
100 	LATServer::Instance()->remove_fd(master_fd);
101     }
102 }
103 
do_read()104 void ClientSession::do_read()
105 {
106     debuglog(("ClientSession::do_read(), connected: %d\n", connected));
107     if (!connected)
108     {
109 	if (!connect_parent())
110 	{
111 	    state = STARTING;
112 
113 	    // Disable reads on the PTY until we are connected (or it fails)
114 	    LATServer::Instance()->set_fd_state(master_fd, true);
115 
116 	    close(slave_fd);
117 	    slave_fd_open = false;
118 	}
119 	else
120 	{
121 	    // Service does not exist or we haven't heard of it yet.
122 	    restart_pty();
123 	}
124     }
125 
126     if (connected)
127     {
128 	read_pty();
129     }
130 }
131 
132 // Called from the slave connection - return the master fd so it can
133 // can do I/O on it.
get_port_fd()134 int ClientSession::get_port_fd()
135 {
136     return master_fd;
137 }
138 
139 // Normal client sessions don't provide feedback on status (though maybe we
140 // should check for other status types....
show_status(unsigned char * node,LAT_StatusEntry * entry)141 void ClientSession::show_status(unsigned char *node, LAT_StatusEntry *entry)
142 {
143     return;
144 }
145 
146 // Called when a PortSession connects to us
start_port()147 void ClientSession::start_port()
148 {
149     return;
150 }
151