Improve ssh_options_copy() and ssh_options_free().

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@345 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
Andreas Schneider
2009-04-02 09:58:59 +00:00
parent 356a8a7631
commit 595a5d9ff2

View File

@@ -79,83 +79,136 @@ void ssh_options_set_port(SSH_OPTIONS *opt, unsigned int port){
opt->bindport=port&0xffff; opt->bindport=port&0xffff;
} }
/** you may need to duplication an option structure if you make several /**
* sessions with the same options.\n * @brief Duplicate an option structure.
* You cannot use twice the same option structure in ssh_session_connect. *
* \brief copies an option structure * If you make several sessions with the same options this is useful. You
* \param opt option structure to copy * cannot use twice the same option structure in ssh_session_connect.
* \returns new copied option structure *
* \see ssh_session_connect() * @param opt Option structure to copy.
*
* @returns New copied option structure, NULL on error.
*
* @see ssh_session_connect()
*/ */
SSH_OPTIONS *ssh_options_copy(SSH_OPTIONS *opt) { SSH_OPTIONS *ssh_options_copy(SSH_OPTIONS *opt) {
SSH_OPTIONS *ret; SSH_OPTIONS *new = NULL;
int i; int i;
ret = ssh_options_new(); new = ssh_options_new();
if (ret == NULL) { if (new == NULL) {
return NULL; return NULL;
} }
ret->fd=opt->fd; if (opt->username) {
ret->port=opt->port; new->username = strdup(opt->username);
if(opt->username) if (new->username == NULL) {
ret->username=strdup(opt->username); goto err;
if(opt->host) }
ret->host=strdup(opt->host); }
if(opt->bindaddr) if (opt->host) {
ret->host=strdup(opt->bindaddr); new->host = strdup(opt->host);
if(opt->identity) if (new->host == NULL) {
ret->identity=strdup(opt->identity); goto err;
if(opt->ssh_dir) }
ret->ssh_dir=strdup(opt->ssh_dir); }
if(opt->known_hosts_file) if (opt->bindaddr) {
ret->known_hosts_file=strdup(opt->known_hosts_file); new->host = strdup(opt->bindaddr);
if(opt->dsakey) if (new->host == NULL) {
ret->dsakey=strdup(opt->dsakey); goto err;
if(opt->rsakey) }
ret->rsakey=strdup(opt->rsakey); }
for(i=0;i<10;++i) if (opt->identity) {
if(opt->wanted_methods[i]) new->identity=strdup(opt->identity);
ret->wanted_methods[i]=strdup(opt->wanted_methods[i]); if (new->identity == NULL) {
ret->auth_function=opt->auth_function; return NULL;
ret->auth_userdata=opt->auth_userdata; }
ret->connect_status_function=opt->connect_status_function; }
ret->connect_status_arg=opt->connect_status_arg; if (opt->ssh_dir) {
ret->timeout=opt->timeout; new->ssh_dir = strdup(opt->ssh_dir);
ret->timeout_usec=opt->timeout_usec; if (new->ssh_dir == NULL) {
ret->ssh2allowed=opt->ssh2allowed; goto err;
ret->ssh1allowed=opt->ssh1allowed; }
ret->log_function=opt->log_function; }
ret->log_verbosity=opt->log_verbosity; if (opt->known_hosts_file) {
return ret; new->known_hosts_file = strdup(opt->known_hosts_file);
if (new->known_hosts_file == NULL) {
goto err;
}
}
if (opt->dsakey) {
new->dsakey = strdup(opt->dsakey);
if (new->dsakey == NULL) {
goto err;
}
}
if (opt->rsakey) {
new->rsakey = strdup(opt->rsakey);
if (new->rsakey == NULL) {
goto err;
}
}
for (i = 0; i < 10; ++i) {
if (opt->wanted_methods[i]) {
new->wanted_methods[i] = strdup(opt->wanted_methods[i]);
if (new->wanted_methods[i] == NULL) {
goto err;
}
}
} }
/** \internal new->fd = opt->fd;
* \brief frees an option structure new->port = opt->port;
* \param opt option structure new->auth_function = opt->auth_function;
new->auth_userdata = opt->auth_userdata;
new->connect_status_function = opt->connect_status_function;
new->connect_status_arg = opt->connect_status_arg;
new->timeout = opt->timeout;
new->timeout_usec = opt->timeout_usec;
new->ssh2allowed = opt->ssh2allowed;
new->ssh1allowed = opt->ssh1allowed;
new->log_function = opt->log_function;
new->log_verbosity = opt->log_verbosity;
return new;
err:
ssh_options_free(new);
return NULL;
}
/** @internal
* @brief Frees an option structure.
*
* @param opt Option structure to free.
*/ */
void ssh_options_free(SSH_OPTIONS *opt) { void ssh_options_free(SSH_OPTIONS *opt) {
int i; int i;
if(opt->username)
free(opt->username); if (opt == NULL) {
if(opt->identity) return;
free(opt->identity); }
/* we don't touch the banner. if the implementation did use it, they have to free it */
if(opt->host) /*
free(opt->host); * We don't touch the banner. If the implementation
if(opt->bindaddr) * did use it, they have to free it
free(opt->bindaddr); */
if(opt->ssh_dir)
free(opt->ssh_dir); SAFE_FREE(opt->username);
if(opt->dsakey) SAFE_FREE(opt->host);
free(opt->dsakey); SAFE_FREE(opt->identity);
if(opt->rsakey) SAFE_FREE(opt->bindaddr);
free(opt->rsakey); SAFE_FREE(opt->ssh_dir);
for(i=0;i<10;i++) SAFE_FREE(opt->known_hosts_file);
if(opt->wanted_methods[i]) SAFE_FREE(opt->dsakey);
SAFE_FREE(opt->rsakey);
for (i = 0; i < 10; i++) {
if (opt->wanted_methods[i]) {
free(opt->wanted_methods[i]); free(opt->wanted_methods[i]);
memset(opt,0,sizeof(SSH_OPTIONS)); }
free(opt); }
ZERO_STRUCTP(opt);
SAFE_FREE(opt);
} }
/** \brief set destination hostname /** \brief set destination hostname