Changeset 7417

Show
Ignore:
Timestamp:
03/03/08 22:03:15 (5 years ago)
Author:
frsyuki
Message:

lang/c/partty: added window size negotiation on host-server comunication

Location:
lang/c/partty/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • lang/c/partty/trunk/emtelnet.cc

    r7411 r7417  
    354354                // will is sent and receive dont 
    355355                // I can't use the option 
    356                 m_do_waiting.reset(c); 
     356                if( m_my_option_handler[(size_t)c] ) { 
     357                        m_my_option_handler[(size_t)c](c, false, *this); 
     358                } 
    357359        } else { 
    358360                // the partner wants not to use the option 
    359361                // the partner can't use the option 
    360362                // reply dont 
    361                 if( m_partner_option_handler[(size_t)c] ) { 
    362                         m_partner_option_handler[(size_t)c](c, false, *this); 
     363                if( m_my_option_handler[(size_t)c] ) { 
     364                        m_my_option_handler[(size_t)c](c, false, *this); 
    363365                } 
    364366                owrite3(IAC, WONT, c); 
  • lang/c/partty/trunk/host.cc

    r7409 r7417  
    1818// FIXME Serverとのコネクションが切断したら再接続する? 
    1919 
    20 reverce_telnetd::reverce_telnetd() : 
     20receiver_telnetd::receiver_telnetd() : 
    2121                emtelnet(this) 
    2222{ 
    23         // TODO 
     23        // use these options 
     24        set_my_option_handler( emtelnet::OPT_SGA, 
     25                        receiver_telnetd::pass_through_handler ); 
     26        set_my_option_handler( emtelnet::OPT_BINARY, 
     27                        receiver_telnetd::pass_through_handler ); 
     28        set_my_option_handler( emtelnet::OPT_NAWS, 
     29                        receiver_telnetd::pass_through_handler ); 
     30 
     31        // supported partner options 
     32        set_partner_option_handler( emtelnet::OPT_SGA, 
     33                        receiver_telnetd::pass_through_handler ); 
     34        set_partner_option_handler( emtelnet::OPT_BINARY, 
     35                        receiver_telnetd::pass_through_handler ); 
     36 
     37        // skip useless negotiation 
    2438} 
    2539 
     
    168182                throw io_error("pty is broken"); 
    169183        } 
    170         // 標準入力のウィンドウサイズが変更されたら子仮想端末にも反映する 
     184        // 標準入力のウィンドウサイズが変更されたら、 
     185        // 子仮想端末に反映し、サーバーにも転送する 
    171186        struct winsize next; 
    172187        get_window_size(fd, &next); 
     
    174189                set_window_size(sh, &next); 
    175190                winsz = next; 
     191                unsigned char sbbuf[4]; 
     192                *((short*)sbbuf) = htons(next.ws_col); 
     193                *((short*)(sbbuf+2)) = htons(next.ws_row); 
     194                m_telnet.send_sb(emtelnet::OPT_NAWS, sbbuf, sizeof(sbbuf)); 
     195                // XXX ウィンドウサイズは後で転送 
    176196        } 
    177197        // lock_codeが含まれていたらm_lockingをトグルする 
  • lang/c/partty/trunk/host.h

    r7409 r7417  
    66namespace Partty { 
    77 
    8 class reverce_telnetd : public emtelnet { 
     8class receiver_telnetd : public emtelnet { 
    99public: 
    10         reverce_telnetd(); 
     10        receiver_telnetd(); 
    1111private: 
    1212        static void pass_through_handler(char cmd, bool sw, emtelnet& base) {} 
     
    3939        static const size_t SHARED_BUFFER_SIZE = 32 * 1024; 
    4040        char shared_buffer[SHARED_BUFFER_SIZE]; 
    41         reverce_telnetd m_telnet; 
     41        receiver_telnetd m_telnet; 
    4242private: 
    4343        struct winsize winsz; 
  • lang/c/partty/trunk/multiplexer.cc

    r7409 r7417  
    1818// FIXME perror -> ログ 
    1919 
    20 filt_telnetd::filt_telnetd() : emtelnet((void*)this) 
     20filt_telnetd::filt_telnetd() : 
     21                emtelnet((void*)this), 
     22                m_enable_ws(true)  // XXX デフォルトtrue 
    2123{ 
    2224        // use these options 
     
    2729        set_my_option_handler( emtelnet::OPT_BINARY, 
    2830                        filt_telnetd::pass_through_handler ); 
     31        set_my_option_handler( emtelnet::OPT_NAWS, 
     32                        filt_telnetd::enable_ws_handler ); 
    2933 
    3034        // supported partner options 
     
    4145        send_will(emtelnet::OPT_BINARY); 
    4246        send_do(emtelnet::OPT_BINARY); 
    43 } 
    44  
    45  
    46 sender_telnetd::sender_telnetd() : emtelnet((void*)this) 
    47 { 
    48         // TODO 
     47 
     48        // window size 
     49        send_will(emtelnet::OPT_NAWS); 
     50} 
     51 
     52void filt_telnetd::send_ws(const char* sbbuf, size_t sz4) 
     53{ 
     54        if(m_enable_ws) { 
     55                send_sb(emtelnet::OPT_NAWS, sbbuf, sz4); 
     56        } 
     57} 
     58 
     59void filt_telnetd::enable_ws_handler(char cmd, bool sw, emtelnet& base) 
     60{ 
     61        static_cast<filt_telnetd&>(base).m_enable_ws = sw; 
     62} 
     63 
     64 
     65sender_telnetd::sender_telnetd() : 
     66                emtelnet((void*)this), 
     67                m_cols(0), m_rows(0), m_ws_changed(false) 
     68{ 
     69        // use these options 
     70        set_my_option_handler( emtelnet::OPT_SGA, 
     71                        sender_telnetd::pass_through_handler ); 
     72        set_my_option_handler( emtelnet::OPT_BINARY, 
     73                        sender_telnetd::pass_through_handler ); 
     74 
     75        // supported partner options 
     76        set_partner_option_handler( emtelnet::OPT_SGA, 
     77                        sender_telnetd::pass_through_handler ); 
     78        set_partner_option_handler( emtelnet::OPT_BINARY, 
     79                        sender_telnetd::pass_through_handler ); 
     80        set_partner_option_handler( emtelnet::OPT_NAWS, 
     81                        sender_telnetd::pass_through_handler ); 
     82 
     83        set_sb_handler(OPT_NAWS, sender_telnetd::window_size_handler); 
     84 
     85        // skip useless negotiation 
     86} 
     87 
     88void sender_telnetd::window_size_handler(char cmd, const char* msg, size_t len, emtelnet& self) 
     89{ 
     90        if(len != 4) { return; } 
     91        short cols = ntohs(*((short*)msg)); 
     92        short rows = ntohs(*((short*)(msg+2))); 
     93        static_cast<sender_telnetd&>(self).ws_change(cols, rows); 
    4994} 
    5095 
     
    208253        guest_set.data(guest).send(SERVER_WELCOME_MESSAGE, strlen(SERVER_WELCOME_MESSAGE), NULL); 
    209254        num_guest++; 
     255        // 初期ウィンドウサイズを設定 
     256        if( m_host_telnet.ws_initialized() ) { 
     257                char sbbuf[4]; 
     258                *((short*)sbbuf) = htons(m_host_telnet.get_rows()); 
     259                *((short*)(sbbuf+2)) = htons(m_host_telnet.get_cols()); 
     260                guest_set.data(guest).send_ws(sbbuf, sizeof(sbbuf)); 
     261        } 
    210262        return 0; 
    211263} 
     
    232284                } 
    233285                m_host_telnet.olength = 0; 
     286        } 
     287        // 画面サイズ 
     288        if( m_host_telnet.ws_changed() ) { 
     289                m_recorder->set_window_size( 
     290                                m_host_telnet.get_rows(), 
     291                                m_host_telnet.get_cols() 
     292                                ); 
     293                if( num_guest > 0 ) { 
     294                        char sbbuf[4]; 
     295                        *((short*)sbbuf) = htons(m_host_telnet.get_rows()); 
     296                        *((short*)(sbbuf+2)) = htons(m_host_telnet.get_cols()); 
     297                        int n = 0; 
     298                        for(int fd = 0; fd < INT_MAX; ++fd) { 
     299                                if( guest_set.test(fd) ) { 
     300                                        guest_set.data(fd).send_ws(sbbuf, sizeof(sbbuf)); 
     301                                        ++n; 
     302                                        if( n >= num_guest ) { break; } 
     303                                } 
     304                        } 
     305                } 
    234306        } 
    235307        if( !m_host_telnet.ilength ) { return 0; } 
  • lang/c/partty/trunk/multiplexer.h

    r7409 r7417  
    2626        inline void get_ibuffer(buffer_t* in); 
    2727        inline void get_obuffer(buffer_t* out); 
     28public: 
     29        void send_ws(const char* sbbuf, size_t sz4); 
    2830private: 
    2931        static void pass_through_handler(char cmd, bool sw, emtelnet& base) {} 
     32        static void enable_ws_handler(char cmd, bool sw, emtelnet& base); 
     33        bool m_enable_ws; 
    3034}; 
    3135 
     
    7276private: 
    7377        static void pass_through_handler(char cmd, bool sw, emtelnet& base) {} 
     78        static void window_size_handler(char cmd, const char* msg, size_t len, emtelnet& self); 
     79public: 
     80        void ws_change(short cols, short rows) { 
     81                m_cols = cols; 
     82                m_rows = rows; 
     83                m_ws_changed = true; 
     84        } 
     85        bool ws_changed(void) const { return m_ws_changed; } 
     86        short get_cols(void) const { return m_cols; } 
     87        short get_rows(void) const { return m_rows; } 
     88        void ws_flush(void) { m_ws_changed = false; } 
     89        bool ws_initialized(void) const { return (m_cols != 0 && m_rows != 0); } 
     90private: 
     91        short m_cols; 
     92        short m_rows; 
     93        bool m_ws_changed; 
    7494}; 
    7595