1 /*
2     Mosh: the mobile shell
3     Copyright 2012 Keith Winstein
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program 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
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18     In addition, as a special exception, the copyright holders give
19     permission to link the code of portions of this program with the
20     OpenSSL library under certain conditions as described in each
21     individual source file, and distribute linked combinations including
22     the two.
23 
24     You must obey the GNU General Public License in all respects for all
25     of the code used other than OpenSSL. If you modify file(s) with this
26     exception, you may extend this exception to your version of the
27     file(s), but you are not obligated to do so. If you do not wish to do
28     so, delete this exception statement from your version. If you delete
29     this exception statement from all source files in the program, then
30     also delete it here.
31 */
32 
33 #ifndef STM_CLIENT_HPP
34 #define STM_CLIENT_HPP
35 
36 #include <sys/ioctl.h>
37 #include <termios.h>
38 #include <string>
39 
40 #include "completeterminal.h"
41 #include "networktransport.h"
42 #include "user.h"
43 #include "terminaloverlay.h"
44 
45 class STMClient {
46 private:
47   std::string ip;
48   std::string port;
49   std::string key;
50 
51   int escape_key;
52   int escape_pass_key;
53   int escape_pass_key2;
54   bool escape_requires_lf;
55   std::wstring escape_key_help;
56 
57   struct termios saved_termios, raw_termios;
58 
59   struct winsize window_size;
60 
61   Terminal::Framebuffer local_framebuffer, new_state;
62   Overlay::OverlayManager overlays;
63   Network::Transport< Network::UserStream, Terminal::Complete > *network;
64   Terminal::Display display;
65 
66   std::wstring connecting_notification;
67   bool repaint_requested, lf_entered, quit_sequence_started;
68   bool clean_shutdown;
69   unsigned int verbose;
70 
71   void main_init( void );
72   void process_network_input( void );
73   bool process_user_input( int fd );
74   bool process_resize( void );
75 
76   void output_new_frame( void );
77 
still_connecting(void)78   bool still_connecting( void ) const
79   {
80     /* Initially, network == NULL */
81     return network && ( network->get_remote_state_num() == 0 );
82   }
83 
84   void resume( void ); /* restore state after SIGCONT */
85 
86 public:
STMClient(const char * s_ip,const char * s_port,const char * s_key,const char * predict_mode,unsigned int s_verbose)87   STMClient( const char *s_ip, const char *s_port, const char *s_key, const char *predict_mode, unsigned int s_verbose )
88     : ip( s_ip ? s_ip : "" ), port( s_port ? s_port : "" ),
89     key( s_key ? s_key : "" ),
90     escape_key( 0x1E ), escape_pass_key( '^' ), escape_pass_key2( '^' ),
91     escape_requires_lf( false ), escape_key_help( L"?" ),
92       saved_termios(), raw_termios(),
93       window_size(),
94       local_framebuffer( 1, 1 ),
95       new_state( 1, 1 ),
96       overlays(),
97       network( NULL ),
98       display( true ), /* use TERM environment var to initialize display */
99       connecting_notification(),
100       repaint_requested( false ),
101       lf_entered( false ),
102       quit_sequence_started( false ),
103       clean_shutdown( false ),
104       verbose( s_verbose )
105   {
106     if ( predict_mode ) {
107       if ( !strcmp( predict_mode, "always" ) ) {
108 	overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Always );
109       } else if ( !strcmp( predict_mode, "never" ) ) {
110 	overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Never );
111       } else if ( !strcmp( predict_mode, "adaptive" ) ) {
112 	overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Adaptive );
113       } else if ( !strcmp( predict_mode, "experimental" ) ) {
114 	overlays.get_prediction_engine().set_display_preference( Overlay::PredictionEngine::Experimental );
115       } else {
116 	fprintf( stderr, "Unknown prediction mode %s.\n", predict_mode );
117 	exit( 1 );
118       }
119     }
120   }
121 
122   void init( void );
123   void shutdown( void );
124   bool main( void );
125 
~STMClient()126   ~STMClient()
127   {
128     if ( network != NULL ) {
129       delete network;
130     }
131   }
132 
133   /* unused */
134   STMClient( const STMClient & );
135   STMClient & operator=( const STMClient & );
136 };
137 
138 #endif
139