@ -1257,14 +1257,17 @@ static void *netconsole(void *vconsole)
{
struct console * con = vconsole ;
char hostname [ MAXHOSTNAMELEN ] = " " ;
char tmp [ 512 ] ;
char inbuf [ 512 ] ;
char outbuf [ 512 ] ;
const char * end_buf = inbuf + sizeof ( inbuf ) ;
char * start_read = inbuf ;
int res ;
struct pollfd fds [ 2 ] ;
if ( gethostname ( hostname , sizeof ( hostname ) - 1 ) )
ast_copy_string ( hostname , " <Unknown> " , sizeof ( hostname ) ) ;
snprintf ( tmp, sizeof ( tmp ) , " %s/%ld/%s \n " , hostname , ( long ) ast_mainpid , ast_get_version ( ) ) ;
fdprint ( con - > fd , tmp ) ;
snprintf ( outbuf, sizeof ( outbuf ) , " %s/%ld/%s \n " , hostname , ( long ) ast_mainpid , ast_get_version ( ) ) ;
fdprint ( con - > fd , outbuf ) ;
for ( ; ; ) {
fds [ 0 ] . fd = con - > fd ;
fds [ 0 ] . events = POLLIN ;
@ -1280,24 +1283,49 @@ static void *netconsole(void *vconsole)
continue ;
}
if ( fds [ 0 ] . revents ) {
res = read_credentials ( con - > fd , tmp , sizeof ( tmp ) - 1 , con ) ;
if ( res < 1 ) {
int cmds_read , bytes_read ;
if ( ( bytes_ read = read_credential s( con - > fd , start_read , end_buf - start_read , con ) ) < 1 ) {
break ;
}
tmp [ res ] = 0 ;
if ( strncmp ( tmp , " cli quit after " , 15 ) = = 0 ) {
ast_cli_command_multiple_full ( con - > uid , con - > gid , con - > fd , res - 15 , tmp + 15 ) ;
/* XXX This will only work if it is the first command, and I'm not sure fixing it is worth the effort. */
if ( strncmp ( inbuf , " cli quit after " , 15 ) = = 0 ) {
ast_cli_command_multiple_full ( con - > uid , con - > gid , con - > fd , bytes_read - 15 , inbuf + 15 ) ;
break ;
}
ast_cli_command_multiple_full ( con - > uid , con - > gid , con - > fd , res , tmp ) ;
/* ast_cli_command_multiple_full will only process individual commands terminated by a
* NULL and not trailing partial commands . */
if ( ! ( cmds_read = ast_cli_command_multiple_full ( con - > uid , con - > gid , con - > fd , bytes_read + start_read - inbuf , inbuf ) ) ) {
/* No commands were read. We either have a short read on the first command
* with space left , or a command that is too long */
if ( start_read + bytes_read < end_buf ) {
start_read + = bytes_read ;
} else {
ast_log ( LOG_ERROR , " Command too long! Skipping \n " ) ;
start_read = inbuf ;
}
continue ;
}
if ( start_read [ bytes_read - 1 ] = = ' \0 ' ) {
/* The read ended on a command boundary, start reading again at the head of inbuf */
start_read = inbuf ;
continue ;
}
/* If we get this far, we have left over characters that have not been processed.
* Advance to the character after the last command read by ast_cli_command_multiple_full .
* We are guaranteed to have at least cmds_read NULLs */
while ( cmds_read - - & & ( start_read = rawmemchr ( start_read , ' \0 ' ) ) ) {
start_read + + ;
}
memmove ( inbuf , start_read , end_buf - start_read ) ;
start_read = end_buf - start_read + inbuf ;
}
if ( fds [ 1 ] . revents ) {
res = read_credentials ( con - > p [ 0 ] , tmp , sizeof ( tmp ) , con ) ;
res = read_credentials ( con - > p [ 0 ] , outbuf, sizeof ( outbuf ) , con ) ;
if ( res < 1 ) {
ast_log ( LOG_ERROR , " read returned %d \n " , res ) ;
break ;
}
res = write ( con - > fd , tmp , res ) ;
res = write ( con - > fd , outbuf , res ) ;
if ( res < 1 )
break ;
}