1
1

Add new callbacks in session and channels

Этот коммит содержится в:
milo 2010-09-29 16:58:48 +02:00 коммит произвёл Aris Adamantiadis
родитель 873e02fc6a
Коммит c4356531f7
4 изменённых файлов: 204 добавлений и 3 удалений

Просмотреть файл

@ -91,6 +91,16 @@ typedef void (*ssh_log_callback) (ssh_session session, int priority,
typedef void (*ssh_status_callback) (ssh_session session, float status, typedef void (*ssh_status_callback) (ssh_session session, float status,
void *userdata); void *userdata);
/**
* @brief SSH global request callback. All global request will go through this
* callback.
* @param session Current session handler
* @param message the actual message
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_global_request_callback) (ssh_session session,
ssh_message message, void *userdata);
/** /**
* The structure to replace libssh functions with appropriate callbacks. * The structure to replace libssh functions with appropriate callbacks.
*/ */
@ -114,6 +124,10 @@ struct ssh_callbacks_struct {
* percentage of connection steps completed. * percentage of connection steps completed.
*/ */
void (*connect_status_function)(void *userdata, float status); void (*connect_status_function)(void *userdata, float status);
/**
* This function will be called each time a global request is received.
*/
ssh_global_request_callback global_request_function;
}; };
typedef struct ssh_callbacks_struct *ssh_callbacks; typedef struct ssh_callbacks_struct *ssh_callbacks;
@ -177,7 +191,7 @@ typedef struct ssh_socket_callbacks_struct *ssh_socket_callbacks;
* @returns nonzero if callback can be called * @returns nonzero if callback can be called
*/ */
#define ssh_callbacks_exists(p,c) (\ #define ssh_callbacks_exists(p,c) (\
( (char *)&((p)-> c) < (char *)(p) + (p)->size ) && \ (p) && ( (char *)&((p)-> c) < (char *)(p) + (p)->size ) && \
((p)-> c != NULL) \ ((p)-> c != NULL) \
) )
@ -226,7 +240,7 @@ struct ssh_packet_callbacks_struct {
typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks; typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
/** /**
* @brief Set the callback functions. * @brief Set the session callback functions.
* *
* This functions sets the callback structure to use your own callback * This functions sets the callback structure to use your own callback
* functions for auth, logging and status. * functions for auth, logging and status.
@ -242,12 +256,147 @@ typedef struct ssh_packet_callbacks_struct *ssh_packet_callbacks;
* *
* @param session The session to set the callback structure. * @param session The session to set the callback structure.
* *
* @param cb The callback itself. * @param cb The callback structure itself.
* *
* @return SSH_OK on success, SSH_ERROR on error. * @return SSH_OK on success, SSH_ERROR on error.
*/ */
LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb); LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
/**
* @brief SSH channel data callback. Called when data is available on a channel
* @param session Current session handler
* @param channel the actual channel
* @param data the data that has been read on the channel
* @param len the length of the data
* @param is_stderr is 0 for stdout or 1 for stderr
* @param userdata Userdata to be passed to the callback function.
*/
typedef int (*ssh_channel_data_callback) (ssh_session session,
ssh_channel channel,
void *data,
uint32_t len,
int is_stderr,
void *userdata);
/**
* @brief SSH channel eof callback. Called when a channel receives EOF
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_eof_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
/**
* @brief SSH channel close callback. Called when a channel is closed by remote peer
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_close_callback) (ssh_session session,
ssh_channel channel,
void *userdata);
/**
* @brief SSH channel signal callback. Called when a channel has received a signal
* @param session Current session handler
* @param channel the actual channel
* @param signal the signal name (without the SIG prefix)
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_signal_callback) (ssh_session session,
ssh_channel channel,
const char *signal,
void *userdata);
/**
* @brief SSH channel exit status callback. Called when a channel has received an exit status
* @param session Current session handler
* @param channel the actual channel
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_exit_status_callback) (ssh_session session,
ssh_channel channel,
int exit_status,
void *userdata);
/**
* @brief SSH channel exit signal callback. Called when a channel has received an exit signal
* @param session Current session handler
* @param channel the actual channel
* @param signal the signal name (without the SIG prefix)
* @param core a boolean telling wether a core has been dumped or not
* @param errmsg the description of the exception
* @param lang the language of the description (format: RFC 3066)
* @param userdata Userdata to be passed to the callback function.
*/
typedef void (*ssh_channel_exit_signal_callback) (ssh_session session,
ssh_channel channel,
const char *signal,
int core,
const char *errmsg,
const char *lang,
void *userdata);
struct ssh_channel_callbacks_struct {
/** DON'T SET THIS use ssh_callbacks_init() instead. */
size_t size;
/**
* User-provided data. User is free to set anything he wants here
*/
void *userdata;
/**
* This functions will be called when there is data available.
*/
ssh_channel_data_callback channel_data_function;
/**
* This functions will be called when the channel has received an EOF.
*/
ssh_channel_eof_callback channel_eof_function;
/**
* This functions will be called when the channel has been closed by remote
*/
ssh_channel_close_callback channel_close_function;
/**
* This functions will be called when a signal has been received
*/
ssh_channel_signal_callback channel_signal_function;
/**
* This functions will be called when an exit status has been received
*/
ssh_channel_exit_status_callback channel_exit_status_function;
/**
* This functions will be called when an exit signal has been received
*/
ssh_channel_exit_signal_callback channel_exit_signal_function;
};
typedef struct ssh_channel_callbacks_struct *ssh_channel_callbacks;
/**
* @brief Set the channel callback functions.
*
* This functions sets the callback structure to use your own callback
* functions for channel data and exceptions
*
* @code
* struct ssh_channel_callbacks_struct cb = {
* .userdata = data,
* .channel_data = my_channel_data_function
* };
* ssh_callbacks_init(&cb);
* ssh_set_channel_callbacks(channel, &cb);
* @endcode
*
* @param channel The channel to set the callback structure.
*
* @param cb The callback structure itself.
*
* @return SSH_OK on success, SSH_ERROR on error.
*/
LIBSSH_API int ssh_set_channel_callbacks(ssh_channel channel,
ssh_channel_callbacks cb);
/** @} */ /** @} */
/** @group libssh_threads /** @group libssh_threads

Просмотреть файл

@ -69,6 +69,7 @@ struct ssh_channel_struct {
int blocking; int blocking;
int exit_status; int exit_status;
enum ssh_channel_request_state_e request_state; enum ssh_channel_request_state_e request_state;
ssh_channel_callbacks callbacks;
}; };
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf); SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);

Просмотреть файл

@ -41,3 +41,21 @@ int ssh_set_callbacks(ssh_session session, ssh_callbacks cb) {
leave_function(); leave_function();
return 0; return 0;
} }
int ssh_set_channel_callbacks(ssh_channel channel, ssh_channel_callbacks cb) {
ssh_session session = NULL;
if (channel == NULL || cb == NULL) {
return SSH_ERROR;
}
session = channel->session;
enter_function();
if(cb->size <= 0 || cb->size > 1024 * sizeof(void *)){
ssh_set_error(session,SSH_FATAL,
"Invalid channel callback passed in (badly initialized)");
leave_function();
return SSH_ERROR;
}
channel->callbacks = cb;
leave_function();
return 0;
}

Просмотреть файл

@ -430,8 +430,10 @@ SSH_PACKET_CALLBACK(channel_rcv_change_window) {
SSH_PACKET_CALLBACK(channel_rcv_data){ SSH_PACKET_CALLBACK(channel_rcv_data){
ssh_channel channel; ssh_channel channel;
ssh_string str; ssh_string str;
ssh_buffer buf;
size_t len; size_t len;
int is_stderr; int is_stderr;
int rest;
(void)user; (void)user;
enter_function(); enter_function();
if(type==SSH2_MSG_CHANNEL_DATA) if(type==SSH2_MSG_CHANNEL_DATA)
@ -495,6 +497,25 @@ SSH_PACKET_CALLBACK(channel_rcv_data){
channel->remote_window); channel->remote_window);
ssh_string_free(str); ssh_string_free(str);
if(ssh_callbacks_exists(channel->callbacks, channel_data_function)) {
if(is_stderr) {
buf = channel->stderr_buffer;
} else {
buf = channel->stdout_buffer;
}
rest = channel->callbacks->channel_data_function(channel->session,
channel,
buffer_get_rest(buf),
buffer_get_rest_len(buf),
is_stderr,
channel->callbacks->userdata);
if(rest > 0) {
buffer_pass_bytes(buf, rest);
channel->local_window += rest;
}
}
leave_function(); leave_function();
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
@ -519,6 +540,12 @@ SSH_PACKET_CALLBACK(channel_rcv_eof) {
/* channel->remote_window = 0; */ /* channel->remote_window = 0; */
channel->remote_eof = 1; channel->remote_eof = 1;
if(ssh_callbacks_exists(channel->callbacks, channel_eof_function)) {
channel->callbacks->channel_eof_function(channel->session,
channel,
channel->callbacks->userdata);
}
leave_function(); leave_function();
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }
@ -560,6 +587,12 @@ SSH_PACKET_CALLBACK(channel_rcv_close) {
* buffer because the eof is ignored until the buffer is empty. * buffer because the eof is ignored until the buffer is empty.
*/ */
if(ssh_callbacks_exists(channel->callbacks, channel_close_function)) {
channel->callbacks->channel_close_function(channel->session,
channel,
channel->callbacks->userdata);
}
leave_function(); leave_function();
return SSH_PACKET_USED; return SSH_PACKET_USED;
} }