@ -149,6 +149,9 @@ static void on_sigint(int signum)
sigint_pending = 1 ;
sigint_pending = 1 ;
}
}
/* set while receiving data for a background session — suppresses live screen writes */
static int suppress_draw = 0 ;
/* ── BPQ / monitor state (shared across all sessions) ─────── */
/* ── BPQ / monitor state (shared across all sessions) ─────── */
int mon_visible = 1 ;
int mon_visible = 1 ;
int mon_tx = 1 ;
int mon_tx = 1 ;
@ -954,11 +957,12 @@ void append_mon(const char *text, int len, int attr)
const char * p = text ;
const char * p = text ;
const char * end = text + len ;
const char * end = text + len ;
int live = ( mon_win ! = NULL & & ! suppress_draw ) ;
S - > mon_part_cur = attr ;
S - > mon_part_cur = attr ;
if ( S - > mon_part_len = = 0 ) S - > mon_part_base = attr ;
if ( S - > mon_part_len = = 0 ) S - > mon_part_base = attr ;
if ( mon_win & & S - > mon_scroll = = 0 )
if ( live & & S - > mon_scroll = = 0 )
wattron ( mon_win , S - > mon_part_cur ) ;
wattron ( mon_win , S - > mon_part_cur ) ;
while ( p < end ) {
while ( p < end ) {
@ -969,7 +973,7 @@ void append_mon(const char *text, int len, int attr)
S - > mon_part [ S - > mon_part_len + + ] = ( char ) 0x1B ;
S - > mon_part [ S - > mon_part_len + + ] = ( char ) 0x1B ;
S - > mon_part [ S - > mon_part_len + + ] = p [ 1 ] ;
S - > mon_part [ S - > mon_part_len + + ] = p [ 1 ] ;
}
}
if ( mon_win & & S - > mon_scroll = = 0 ) {
if ( live & & S - > mon_scroll = = 0 ) {
wattroff ( mon_win , S - > mon_part_cur ) ;
wattroff ( mon_win , S - > mon_part_cur ) ;
wattron ( mon_win , na ) ;
wattron ( mon_win , na ) ;
}
}
@ -984,19 +988,19 @@ void append_mon(const char *text, int len, int attr)
if ( S - > mon_sbuf_count < SCRL_MAX ) S - > mon_sbuf_count + + ;
if ( S - > mon_sbuf_count < SCRL_MAX ) S - > mon_sbuf_count + + ;
S - > mon_part_len = 0 ;
S - > mon_part_len = 0 ;
S - > mon_part_base = S - > mon_part_cur ;
S - > mon_part_base = S - > mon_part_cur ;
if ( mon_win & & S - > mon_scroll = = 0 )
if ( live & & S - > mon_scroll = = 0 )
waddch ( mon_win , ' \n ' ) ;
waddch ( mon_win , ' \n ' ) ;
p + + ;
p + + ;
} else if ( c > = 32 & & c < 127 ) {
} else if ( c > = 32 & & c < 127 ) {
if ( S - > mon_part_len < SCRL_W - 1 )
if ( S - > mon_part_len < SCRL_W - 1 )
S - > mon_part [ S - > mon_part_len + + ] = ( char ) c ;
S - > mon_part [ S - > mon_part_len + + ] = ( char ) c ;
if ( mon_win & & S - > mon_scroll = = 0 )
if ( live & & S - > mon_scroll = = 0 )
waddch ( mon_win , c ) ;
waddch ( mon_win , c ) ;
p + + ;
p + + ;
} else { p + + ; }
} else { p + + ; }
}
}
if ( mon_win & & S - > mon_scroll = = 0 ) {
if ( live & & S - > mon_scroll = = 0 ) {
wattroff ( mon_win , S - > mon_part_cur ) ;
wattroff ( mon_win , S - > mon_part_cur ) ;
wrefresh ( mon_win ) ;
wrefresh ( mon_win ) ;
if ( input_win ) wrefresh ( input_win ) ;
if ( input_win ) wrefresh ( input_win ) ;
@ -1009,11 +1013,12 @@ void append_out(const char *text, int len, int attr)
const char * p = text ;
const char * p = text ;
const char * end = text + len ;
const char * end = text + len ;
int live = ( out_win ! = NULL & & ! suppress_draw ) ;
S - > out_part_cur = attr ;
S - > out_part_cur = attr ;
if ( S - > out_part_len = = 0 ) S - > out_part_base = attr ;
if ( S - > out_part_len = = 0 ) S - > out_part_base = attr ;
if ( out_win & & S - > out_scroll = = 0 )
if ( live & & S - > out_scroll = = 0 )
wattron ( out_win , S - > out_part_cur ) ;
wattron ( out_win , S - > out_part_cur ) ;
while ( p < end ) {
while ( p < end ) {
@ -1024,7 +1029,7 @@ void append_out(const char *text, int len, int attr)
S - > out_part [ S - > out_part_len + + ] = ( char ) 0x1B ;
S - > out_part [ S - > out_part_len + + ] = ( char ) 0x1B ;
S - > out_part [ S - > out_part_len + + ] = p [ 1 ] ;
S - > out_part [ S - > out_part_len + + ] = p [ 1 ] ;
}
}
if ( out_win & & S - > out_scroll = = 0 ) {
if ( live & & S - > out_scroll = = 0 ) {
wattroff ( out_win , S - > out_part_cur ) ;
wattroff ( out_win , S - > out_part_cur ) ;
wattron ( out_win , na ) ;
wattron ( out_win , na ) ;
}
}
@ -1039,19 +1044,19 @@ void append_out(const char *text, int len, int attr)
if ( S - > out_sbuf_count < SCRL_MAX ) S - > out_sbuf_count + + ;
if ( S - > out_sbuf_count < SCRL_MAX ) S - > out_sbuf_count + + ;
S - > out_part_len = 0 ;
S - > out_part_len = 0 ;
S - > out_part_base = S - > out_part_cur ;
S - > out_part_base = S - > out_part_cur ;
if ( out_win & & S - > out_scroll = = 0 )
if ( live & & S - > out_scroll = = 0 )
waddch ( out_win , ' \n ' ) ;
waddch ( out_win , ' \n ' ) ;
p + + ;
p + + ;
} else if ( c > = 32 & & c < 127 ) {
} else if ( c > = 32 & & c < 127 ) {
if ( S - > out_part_len < SCRL_W - 1 )
if ( S - > out_part_len < SCRL_W - 1 )
S - > out_part [ S - > out_part_len + + ] = ( char ) c ;
S - > out_part [ S - > out_part_len + + ] = ( char ) c ;
if ( out_win & & S - > out_scroll = = 0 )
if ( live & & S - > out_scroll = = 0 )
waddch ( out_win , c ) ;
waddch ( out_win , c ) ;
p + + ;
p + + ;
} else { p + + ; }
} else { p + + ; }
}
}
if ( out_win & & S - > out_scroll = = 0 ) {
if ( live & & S - > out_scroll = = 0 ) {
wattroff ( out_win , S - > out_part_cur ) ;
wattroff ( out_win , S - > out_part_cur ) ;
wrefresh ( out_win ) ;
wrefresh ( out_win ) ;
if ( input_win ) wrefresh ( input_win ) ;
if ( input_win ) wrefresh ( input_win ) ;
@ -3165,27 +3170,46 @@ void interactive_loop(void)
draw_status ( ) ;
draw_status ( ) ;
/* Watch stdin + every connected session's socket */
FD_ZERO ( & readfds ) ;
FD_ZERO ( & readfds ) ;
FD_SET ( STDIN_FILENO , & readfds ) ;
FD_SET ( STDIN_FILENO , & readfds ) ;
if ( S - > connected & & S - > sock > = 0 ) FD_SET ( S - > sock , & readfds ) ;
int maxfd = STDIN_FILENO ;
for ( int i = 0 ; i < MAX_SESSIONS ; i + + ) {
if ( sessions [ i ] . active & & sessions [ i ] . connected & & sessions [ i ] . sock > = 0 ) {
FD_SET ( sessions [ i ] . sock , & readfds ) ;
if ( sessions [ i ] . sock > maxfd ) maxfd = sessions [ i ] . sock ;
}
}
tv . tv_sec = 1 ;
tv . tv_sec = 1 ;
tv . tv_usec = 0 ;
tv . tv_usec = 0 ;
int maxfd = ( S - > connected & & S - > sock > STDIN_FILENO ) ? S - > sock : STDIN_FILENO ;
int ready = select ( maxfd + 1 , & readfds , NULL , NULL , & tv ) ;
int ready = select ( maxfd + 1 , & readfds , NULL , NULL , & tv ) ;
if ( ready < 0 ) continue ;
if ( ready < 0 ) continue ;
/* Network data */
/* Network data — process all active sessions */
if ( S - > connected & & S - > sock > = 0 & & FD_ISSET ( S - > sock , & readfds ) ) {
Session * active = S ;
for ( int i = 0 ; i < MAX_SESSIONS ; i + + ) {
if ( ! sessions [ i ] . active | | ! sessions [ i ] . connected | | sessions [ i ] . sock < 0 )
continue ;
if ( ! FD_ISSET ( sessions [ i ] . sock , & readfds ) )
continue ;
int is_bg = ( & sessions [ i ] ! = active ) ;
S = & sessions [ i ] ;
if ( is_bg ) suppress_draw = 1 ;
int n = recv ( S - > sock , recv_buf , sizeof ( recv_buf ) - 1 , 0 ) ;
int n = recv ( S - > sock , recv_buf , sizeof ( recv_buf ) - 1 , 0 ) ;
if ( n > 0 ) {
if ( n > 0 ) {
bpq_process ( recv_buf , n ) ;
bpq_process ( recv_buf , n ) ;
draw_input ( ) ;
if ( ! is_bg ) draw_input ( ) ;
} else if ( n = = 0 | | ( n < 0 & & errno ! = EAGAIN ) ) {
} else if ( n = = 0 | | ( n < 0 & & errno ! = EAGAIN ) ) {
append_out ( " \n *** Server closed connection *** \n " , 33 ,
append_out ( " \n *** Server closed connection *** \n " , 33 ,
COLOR_PAIR ( CP_RED ) ) ;
COLOR_PAIR ( CP_RED ) ) ;
tcp_disconnect ( ) ;
tcp_disconnect ( ) ;
}
}
suppress_draw = 0 ;
S = active ;
}
}
/* Keyboard */
/* Keyboard */