#include "config.h"
#include <errno.h>
#include <limits.h>
#ifndef _WIN32
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include "libssh/priv.h"
#include "libssh/string.h"
#define STRING_SIZE_MAX 0x10000000
struct ssh_string_struct *ssh_string_new(size_t size)
{
struct ssh_string_struct *str = NULL;
if (size > STRING_SIZE_MAX) {
errno = EINVAL;
return NULL;
}
str = malloc(sizeof(struct ssh_string_struct) + size);
if (str == NULL) {
return NULL;
}
str->size = htonl(size);
str->data[0] = 0;
return str;
}
int ssh_string_fill(struct ssh_string_struct *s, const void *data, size_t len) {
if ((s == NULL) || (data == NULL) ||
(len == 0) || (len > ssh_string_len(s))) {
return -1;
}
memcpy(s->data, data, len);
return 0;
}
struct ssh_string_struct *ssh_string_from_char(const char *what) {
struct ssh_string_struct *ptr;
size_t len;
if(what == NULL) {
errno = EINVAL;
return NULL;
}
len = strlen(what);
ptr = ssh_string_new(len);
if (ptr == NULL) {
return NULL;
}
memcpy(ptr->data, what, len);
return ptr;
}
size_t ssh_string_len(struct ssh_string_struct *s) {
size_t size;
if (s == NULL) {
return 0;
}
size = ntohl(s->size);
if (size > 0 && size <= STRING_SIZE_MAX) {
return size;
}
return 0;
}
const char *ssh_string_get_char(struct ssh_string_struct *s)
{
if (s == NULL) {
return NULL;
}
s->data[ssh_string_len(s)] = '\0';
return (const char *) s->data;
}
char *ssh_string_to_char(struct ssh_string_struct *s) {
size_t len;
char *new;
if (s == NULL) {
return NULL;
}
len = ssh_string_len(s);
if (len + 1 < len) {
return NULL;
}
new = malloc(len + 1);
if (new == NULL) {
return NULL;
}
memcpy(new, s->data, len);
new[len] = '\0';
return new;
}
void ssh_string_free_char(char *s) {
SAFE_FREE(s);
}
struct ssh_string_struct *ssh_string_copy(struct ssh_string_struct *s) {
struct ssh_string_struct *new;
size_t len;
if (s == NULL) {
return NULL;
}
len = ssh_string_len(s);
if (len == 0) {
return NULL;
}
new = ssh_string_new(len);
if (new == NULL) {
return NULL;
}
memcpy(new->data, s->data, len);
return new;
}
void ssh_string_burn(struct ssh_string_struct *s) {
if (s == NULL || s->size == 0) {
return;
}
explicit_bzero(s->data, ssh_string_len(s));
}
void *ssh_string_data(struct ssh_string_struct *s) {
if (s == NULL) {
return NULL;
}
return s->data;
}
void ssh_string_free(struct ssh_string_struct *s) {
SAFE_FREE(s);
}