mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-05 20:55:46 +03:00
More doxygen documentation (internal set)
split of the sftp_async_read function git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@188 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
1272
Doxyfile.internal
Normal file
1272
Doxyfile.internal
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,17 +24,21 @@ install-doc: doxygen
|
|||||||
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
|
$(INSTALL) -d $(DESTDIR)$(mandir)/man3
|
||||||
$(INSTALL) --mode=644 doxygen/man/man3/* $(DESTDIR)$(mandir)/man3
|
$(INSTALL) --mode=644 doxygen/man/man3/* $(DESTDIR)$(mandir)/man3
|
||||||
|
|
||||||
doxygen:
|
doxygen: clean-local
|
||||||
@echo "Running doxygen..."
|
@echo "Running doxygen..."
|
||||||
doxygen $(srcdir)/Doxyfile
|
doxygen $(srcdir)/Doxyfile
|
||||||
|
doxygen-dev: clean-local
|
||||||
|
@echo "Running internal doxygen"
|
||||||
|
doxygen $(srcdir)/Doxyfile.internal
|
||||||
else
|
else
|
||||||
doxygen:
|
doxygen:
|
||||||
|
doxygen-dev:
|
||||||
install-doc: doxygen
|
install-doc: doxygen
|
||||||
endif
|
endif
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
-rm -rf doxygen
|
-rm -rf doxygen
|
||||||
|
|
||||||
EXTRA_DIST = Doxyfile
|
EXTRA_DIST = Doxyfile Doxyfile.internal
|
||||||
|
|
||||||
CLEANFILES = samplesftp
|
CLEANFILES = samplesftp
|
||||||
|
@@ -146,7 +146,8 @@ int sftp_file_close(SFTP_FILE *file);
|
|||||||
/* access are the sames than the ones from ansi fopen() */
|
/* access are the sames than the ones from ansi fopen() */
|
||||||
SFTP_FILE *sftp_open(SFTP_SESSION *session, char *file, int access, SFTP_ATTRIBUTES *attr);
|
SFTP_FILE *sftp_open(SFTP_SESSION *session, char *file, int access, SFTP_ATTRIBUTES *attr);
|
||||||
int sftp_read(SFTP_FILE *file, void *dest, int len);
|
int sftp_read(SFTP_FILE *file, void *dest, int len);
|
||||||
int sftp_async_read(SFTP_FILE *file, void *data, int len, int *id);
|
u32 sftp_async_read_begin(SFTP_FILE *file, int len);
|
||||||
|
int sftp_async_read(SFTP_FILE *file, void *data, int len, u32 id);
|
||||||
int sftp_write(SFTP_FILE *file, void *source, int len);
|
int sftp_write(SFTP_FILE *file, void *source, int len);
|
||||||
void sftp_seek(SFTP_FILE *file, int new_offset);
|
void sftp_seek(SFTP_FILE *file, int new_offset);
|
||||||
unsigned long sftp_tell(SFTP_FILE *file);
|
unsigned long sftp_tell(SFTP_FILE *file);
|
||||||
|
167
libssh/sftp.c
167
libssh/sftp.c
@@ -50,6 +50,11 @@ MA 02111-1307, USA. */
|
|||||||
void sftp_enqueue(SFTP_SESSION *session, SFTP_MESSAGE *msg);
|
void sftp_enqueue(SFTP_SESSION *session, SFTP_MESSAGE *msg);
|
||||||
static void sftp_message_free(SFTP_MESSAGE *msg);
|
static void sftp_message_free(SFTP_MESSAGE *msg);
|
||||||
|
|
||||||
|
/** \brief start a new SFTP session
|
||||||
|
* \param session the SSH session
|
||||||
|
* \returns a SFTP_SESSION handle on success
|
||||||
|
* \returns NULL in case of an error
|
||||||
|
*/
|
||||||
SFTP_SESSION *sftp_new(SSH_SESSION *session){
|
SFTP_SESSION *sftp_new(SSH_SESSION *session){
|
||||||
SFTP_SESSION *sftp=malloc(sizeof(SFTP_SESSION));
|
SFTP_SESSION *sftp=malloc(sizeof(SFTP_SESSION));
|
||||||
enter_function();
|
enter_function();
|
||||||
@@ -120,6 +125,9 @@ int sftp_server_init(SFTP_SESSION *sftp){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** \brief Close and deallocate a SFTP session
|
||||||
|
* \param sftp the SFTP session handle
|
||||||
|
*/
|
||||||
void sftp_free(SFTP_SESSION *sftp){
|
void sftp_free(SFTP_SESSION *sftp){
|
||||||
struct request_queue *ptr;
|
struct request_queue *ptr;
|
||||||
channel_send_eof(sftp->channel);
|
channel_send_eof(sftp->channel);
|
||||||
@@ -347,8 +355,11 @@ SFTP_MESSAGE *sftp_dequeue(SFTP_SESSION *session, u32 id){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assigns a new sftp ID for new requests and assures there is no collision between them. */
|
/** \internal
|
||||||
u32 sftp_get_new_id(SFTP_SESSION *session){
|
* \brief assigns a new sftp ID for new requests and assures there is no collision between them.
|
||||||
|
* returns a new ID ready to use in a request
|
||||||
|
*/
|
||||||
|
inline u32 sftp_get_new_id(SFTP_SESSION *session){
|
||||||
return ++session->id_counter;
|
return ++session->id_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,7 +419,13 @@ SFTP_FILE *parse_handle_msg(SFTP_MESSAGE *msg){
|
|||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
/** \brief open a directory
|
||||||
|
* \param sftp SFTP session handle
|
||||||
|
* \param path path to the directory
|
||||||
|
* \return a SFTP_DIR handle
|
||||||
|
* \see sftp_readdir()
|
||||||
|
* \see sftp_dir_close()
|
||||||
|
*/
|
||||||
SFTP_DIR *sftp_opendir(SFTP_SESSION *sftp, char *path){
|
SFTP_DIR *sftp_opendir(SFTP_SESSION *sftp, char *path){
|
||||||
SFTP_DIR *dir=NULL;
|
SFTP_DIR *dir=NULL;
|
||||||
SFTP_FILE *file;
|
SFTP_FILE *file;
|
||||||
@@ -700,10 +717,23 @@ SFTP_ATTRIBUTES *sftp_parse_attr(SFTP_SESSION *session, BUFFER *buf,int expectna
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief return the version of the SFTP protocol supported by the server
|
||||||
|
* \param sftp SFTP session handle
|
||||||
|
* \returns server version
|
||||||
|
*/
|
||||||
int sftp_server_version(SFTP_SESSION *sftp){
|
int sftp_server_version(SFTP_SESSION *sftp){
|
||||||
return sftp->server_version;
|
return sftp->server_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Read file attributes of a directory
|
||||||
|
* \param sftp SFTP session handle
|
||||||
|
* \param dir SFTP_DIR open directory handle
|
||||||
|
* \return a SFTP_ATTRIBUTE handle
|
||||||
|
* \return NULL End of directory
|
||||||
|
* \see sftp_opendir()
|
||||||
|
* \see sftp_attribute_free()
|
||||||
|
* \see sftp_dir_close()
|
||||||
|
*/
|
||||||
SFTP_ATTRIBUTES *sftp_readdir(SFTP_SESSION *sftp, SFTP_DIR *dir){
|
SFTP_ATTRIBUTES *sftp_readdir(SFTP_SESSION *sftp, SFTP_DIR *dir){
|
||||||
BUFFER *payload;
|
BUFFER *payload;
|
||||||
u32 id;
|
u32 id;
|
||||||
@@ -766,10 +796,19 @@ SFTP_ATTRIBUTES *sftp_readdir(SFTP_SESSION *sftp, SFTP_DIR *dir){
|
|||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Tell if the directory has reached End Of File
|
||||||
|
* \param dir SFTP_DIR open handle
|
||||||
|
* \returns non-zero value if the directory has reached EOF
|
||||||
|
* \see sftp_readdir()
|
||||||
|
*/
|
||||||
int sftp_dir_eof(SFTP_DIR *dir){
|
int sftp_dir_eof(SFTP_DIR *dir){
|
||||||
return (dir->eof);
|
return (dir->eof);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Free a SFTP_ATTRIBUTE handle
|
||||||
|
* \param file SFTP_ATTRIBUTE handle to free
|
||||||
|
* \see sftp_readdir()
|
||||||
|
*/
|
||||||
void sftp_attributes_free(SFTP_ATTRIBUTES *file){
|
void sftp_attributes_free(SFTP_ATTRIBUTES *file){
|
||||||
if(file->name)
|
if(file->name)
|
||||||
free(file->name);
|
free(file->name);
|
||||||
@@ -823,8 +862,14 @@ static int sftp_handle_close(SFTP_SESSION *sftp, STRING *handle){
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Close an open file
|
||||||
|
* \param file SFTP_FILE handle to an open file
|
||||||
|
* \returns SSH_NO_ERROR File closed successfully
|
||||||
|
* \returns SSH_ERROR An error happened
|
||||||
|
* \see sftp_file_open()
|
||||||
|
*/
|
||||||
int sftp_file_close(SFTP_FILE *file){
|
int sftp_file_close(SFTP_FILE *file){
|
||||||
int err=0;
|
int err=SSH_NO_ERROR;
|
||||||
if(file->name)
|
if(file->name)
|
||||||
free(file->name);
|
free(file->name);
|
||||||
if(file->handle){
|
if(file->handle){
|
||||||
@@ -835,8 +880,14 @@ int sftp_file_close(SFTP_FILE *file){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Close an open directory
|
||||||
|
* \param dir SFTP_DIR handle to an open directory
|
||||||
|
* \returns SSH_NO_ERROR directory closed successfully
|
||||||
|
* \returns SSH_ERROR An error happened
|
||||||
|
* \see sftp_opendir()
|
||||||
|
*/
|
||||||
int sftp_dir_close(SFTP_DIR *dir){
|
int sftp_dir_close(SFTP_DIR *dir){
|
||||||
int err=0;
|
int err=SSH_NO_ERROR;
|
||||||
if(dir->name)
|
if(dir->name)
|
||||||
free(dir->name);
|
free(dir->name);
|
||||||
if(dir->handle){
|
if(dir->handle){
|
||||||
@@ -849,6 +900,9 @@ int sftp_dir_close(SFTP_DIR *dir){
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Open a remote file
|
||||||
|
* \todo please complete doc
|
||||||
|
*/
|
||||||
SFTP_FILE *sftp_open(SFTP_SESSION *sftp, char *file, int access, SFTP_ATTRIBUTES *attr){
|
SFTP_FILE *sftp_open(SFTP_SESSION *sftp, char *file, int access, SFTP_ATTRIBUTES *attr){
|
||||||
SFTP_FILE *handle;
|
SFTP_FILE *handle;
|
||||||
SFTP_MESSAGE *msg=NULL;
|
SFTP_MESSAGE *msg=NULL;
|
||||||
@@ -982,49 +1036,67 @@ int sftp_read(SFTP_FILE *handle, void *data, int len){
|
|||||||
|
|
||||||
/** This function does an asynchronous read on a file. Its goal is to avoid the slowdowns related to
|
/** This function does an asynchronous read on a file. Its goal is to avoid the slowdowns related to
|
||||||
* the request/response pattern of a synchronous read.\n
|
* the request/response pattern of a synchronous read.\n
|
||||||
* To use if, you must call the function two times.\n
|
* To do so, you must call 2 functions : sftp_async_read_begin() and sftp_async_read().\n
|
||||||
* The first time, *id must be a pointer to an integer containing 0. The function will always return SSH_AGAIN the first time.\n
|
* The first step is to call sftp_async_read_begin(). This function returns a request identifier.\n
|
||||||
* The second time, the function will block until the data have been read, and will return the number of bytes read.\n
|
* The second step is to call sftp_async_read using the said identifier.\n
|
||||||
* If the file is opened in non-blocking mode, the second-time reading will return SSH_AGAIN until the data are available.\n
|
* \brief Start an asynchronous read on a file
|
||||||
* \brief Asynchronous read on a file
|
* \param file SFTP_FILE handle on an open file
|
||||||
* \param file the file handle
|
* \param len Length of data to be read
|
||||||
* \param data pointer to the data to be written
|
* \return A u32 identifier corresponding to the sent request.
|
||||||
* \param len length of data to be read
|
* \warning When calling this function, the internal offset is updated
|
||||||
* \param id a pointer to an identifier
|
* corresponding to the len parameter.
|
||||||
* \return 0 When the file is EOF\n
|
* \warning A call to sftp_async_read_begin() sends a request to the server. When the server answers,
|
||||||
* SSH_AGAIN the function has to be called again\n
|
* libssh allocates memory to store it until sftp_async_read() is called.\n
|
||||||
* SSH_ERROR in case of error\n
|
* Not calling sftp_async_read() will lead to memory leaks.
|
||||||
* otherwise, the number of bytes read is returned
|
* \see sftp_async_read()
|
||||||
* \warning when calling the function for the first time, the internal offset is updated
|
* \see sftp_open()
|
||||||
* corresponding to the len parameter. If the length effectively read is different from the
|
|
||||||
* len parameter, every following read() will be out of sync.
|
|
||||||
* */
|
* */
|
||||||
int sftp_async_read(SFTP_FILE *file, void *data, int len, int *id){
|
|
||||||
SFTP_MESSAGE *msg=NULL;
|
u32 sftp_async_read_begin(SFTP_FILE *file, int len){
|
||||||
STATUS_MESSAGE *status;
|
|
||||||
SFTP_SESSION *sftp=file->sftp;
|
SFTP_SESSION *sftp=file->sftp;
|
||||||
STRING *datastring;
|
|
||||||
int err=0;
|
|
||||||
BUFFER *buffer;
|
BUFFER *buffer;
|
||||||
if(id==NULL){
|
u32 id;
|
||||||
ssh_set_error(sftp->session,SSH_REQUEST_DENIED,"id parameter must not be null");
|
sftp_function_start();
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(file->eof)
|
|
||||||
return 0;
|
|
||||||
if(*id==0){
|
|
||||||
// launch a new request
|
|
||||||
buffer=buffer_new();
|
buffer=buffer_new();
|
||||||
*id=sftp_get_new_id(sftp);
|
id=sftp_get_new_id(sftp);
|
||||||
buffer_add_u32(buffer,*id);
|
buffer_add_u32(buffer,id);
|
||||||
buffer_add_ssh_string(buffer,file->handle);
|
buffer_add_ssh_string(buffer,file->handle);
|
||||||
buffer_add_u64(buffer,htonll(file->offset));
|
buffer_add_u64(buffer,htonll(file->offset));
|
||||||
buffer_add_u32(buffer,htonl(len));
|
buffer_add_u32(buffer,htonl(len));
|
||||||
sftp_packet_write(sftp,SSH_FXP_READ,buffer);
|
sftp_packet_write(sftp,SSH_FXP_READ,buffer);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
file->offset += len; // assume we'll read len bytes
|
file->offset += len; // assume we'll read len bytes
|
||||||
return SSH_AGAIN; // must call back
|
sftp_function_end();
|
||||||
} else {
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief Wait for an asynchronous read to complete, and save the data
|
||||||
|
* \param file The SFTP_FILE handle on the file
|
||||||
|
* \param data Pointer on the destination buffer
|
||||||
|
* \param size Size of the destination buffer. It should be bigger or equal
|
||||||
|
* to the length parameter of the sftp_async_read_begin() call
|
||||||
|
* \param id Identifier returned by sftp_async_read_begin()
|
||||||
|
* \return SSH_ERROR on error
|
||||||
|
* \return SSH_AGAIN if the file is opened in nonblocking mode and the request hasn't been
|
||||||
|
* executed yet
|
||||||
|
* \return 0 on end of file
|
||||||
|
* \return Number of bytes read otherwise
|
||||||
|
* \warning A call to this function with an invalid identifier will never return
|
||||||
|
* \see sftp_async_read_begin()
|
||||||
|
*/
|
||||||
|
int sftp_async_read(SFTP_FILE *file, void *data, int size, u32 id){
|
||||||
|
SFTP_MESSAGE *msg=NULL;
|
||||||
|
STATUS_MESSAGE *status;
|
||||||
|
SFTP_SESSION *sftp=file->sftp;
|
||||||
|
STRING *datastring;
|
||||||
|
int err=0;
|
||||||
|
int len;
|
||||||
|
sftp_function_start();
|
||||||
|
if(file->eof){
|
||||||
|
sftp_function_end();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// handle an existing request
|
// handle an existing request
|
||||||
while(!msg){
|
while(!msg){
|
||||||
if (file->nonblocking){
|
if (file->nonblocking){
|
||||||
@@ -1036,9 +1108,8 @@ int sftp_async_read(SFTP_FILE *file, void *data, int len, int *id){
|
|||||||
if(sftp_read_and_dispatch(sftp))
|
if(sftp_read_and_dispatch(sftp))
|
||||||
/* something nasty has happened */
|
/* something nasty has happened */
|
||||||
return -1;
|
return -1;
|
||||||
msg=sftp_dequeue(sftp,*id);
|
msg=sftp_dequeue(sftp,id);
|
||||||
}
|
}
|
||||||
*id=0;
|
|
||||||
switch (msg->packet_type){
|
switch (msg->packet_type){
|
||||||
case SSH_FXP_STATUS:
|
case SSH_FXP_STATUS:
|
||||||
status=parse_status_msg(msg);
|
status=parse_status_msg(msg);
|
||||||
@@ -1051,19 +1122,22 @@ int sftp_async_read(SFTP_FILE *file, void *data, int len, int *id){
|
|||||||
} else
|
} else
|
||||||
file->eof=1;
|
file->eof=1;
|
||||||
status_msg_free(status);
|
status_msg_free(status);
|
||||||
|
sftp_function_end();
|
||||||
return err?err:0;
|
return err?err:0;
|
||||||
case SSH_FXP_DATA:
|
case SSH_FXP_DATA:
|
||||||
datastring=buffer_get_ssh_string(msg->payload);
|
datastring=buffer_get_ssh_string(msg->payload);
|
||||||
sftp_message_free(msg);
|
sftp_message_free(msg);
|
||||||
if(!datastring){
|
if(!datastring){
|
||||||
ssh_set_error(sftp->session,SSH_FATAL,"Received invalid DATA packet from sftp server");
|
ssh_set_error(sftp->session,SSH_FATAL,"Received invalid DATA packet from sftp server");
|
||||||
|
sftp_function_end();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(string_len(datastring)>len){
|
if(string_len(datastring)>size){
|
||||||
ssh_set_error(sftp->session,SSH_FATAL,"Received a too big DATA packet from sftp server : %d and asked for %d",
|
ssh_set_error(sftp->session,SSH_FATAL,"Received a too big DATA packet from sftp server : %d and asked for %d",
|
||||||
string_len(datastring),len);
|
string_len(datastring),size);
|
||||||
free(datastring);
|
free(datastring);
|
||||||
return -1;
|
sftp_function_end();
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
len=string_len(datastring);
|
len=string_len(datastring);
|
||||||
//handle->offset+=len;
|
//handle->offset+=len;
|
||||||
@@ -1071,15 +1145,16 @@ int sftp_async_read(SFTP_FILE *file, void *data, int len, int *id){
|
|||||||
* and effective lengths are different */
|
* and effective lengths are different */
|
||||||
memcpy(data,datastring->string,len);
|
memcpy(data,datastring->string,len);
|
||||||
free(datastring);
|
free(datastring);
|
||||||
|
sftp_function_end();
|
||||||
return len;
|
return len;
|
||||||
default:
|
default:
|
||||||
ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during read!",msg->packet_type);
|
ssh_set_error(sftp->session,SSH_FATAL,"Received message %d during read!",msg->packet_type);
|
||||||
sftp_message_free(msg);
|
sftp_message_free(msg);
|
||||||
return -1;
|
sftp_function_end();
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sftp_write(SFTP_FILE *file, void *data, int len){
|
int sftp_write(SFTP_FILE *file, void *data, int len){
|
||||||
SFTP_MESSAGE *msg=NULL;
|
SFTP_MESSAGE *msg=NULL;
|
||||||
STATUS_MESSAGE *status;
|
STATUS_MESSAGE *status;
|
||||||
|
Reference in New Issue
Block a user