1
0
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:
Aris Adamantiadis
2008-11-05 16:42:43 +00:00
parent 64e73b8d8a
commit 11e3d3ebab
4 changed files with 1449 additions and 97 deletions

1272
Doxyfile.internal Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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);

View File

@@ -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;