SilcSFTPHandle handle;
handle = silc_calloc(1, sizeof(*handle));
+ if (!handle)
+ return NULL;
handle->data = silc_calloc(data_len, sizeof(*handle->data));
+ if (!handle->data)
+ return NULL;
memcpy(handle->data, data, data_len);
handle->data_len = data_len;
hdata = (unsigned char *)va_arg(vp, unsigned char *);
hdata_len = (SilcUInt32)va_arg(vp, SilcUInt32);
handle = silc_sftp_handle_create(hdata, hdata_len);
+ if (!handle) {
+ if (req->handle)
+ (*req->handle)((SilcSFTP)sftp, status, NULL, req->context);
+ break;
+ }
if (req->handle)
(*req->handle)((SilcSFTP)sftp, status, handle, req->context);
return NULL;
sftp = silc_calloc(1, sizeof(*sftp));
+ if (!sftp)
+ return NULL;
sftp->send_packet = send_packet;
sftp->send_context = send_context;
sftp->version = callback;
SILC_LOG_DEBUG(("Open request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_OPEN;
req->handle = callback;
silc_list_add(client->requests, req);
attrs_buf = silc_sftp_attr_encode(attrs);
+ if (attrs_buf)
+ return;
len = 4 + 4 + strlen(filename) + 4 + attrs_buf->len;
silc_sftp_send_packet(client, req->type, len,
SILC_LOG_DEBUG(("Close request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_CLOSE;
req->status = callback;
SILC_LOG_DEBUG(("Read request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_READ;
req->data = callback;
SILC_LOG_DEBUG(("Write request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_WRITE;
req->status = callback;
SILC_LOG_DEBUG(("Remove request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_REMOVE;
req->status = callback;
SILC_LOG_DEBUG(("Rename request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_RENAME;
req->status = callback;
SILC_LOG_DEBUG(("Mkdir request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_MKDIR;
req->status = callback;
silc_list_add(client->requests, req);
attrs_buf = silc_sftp_attr_encode(attrs);
+ if (attrs_buf)
+ return;
len = 4 + 4 + strlen(path) + attrs_buf->len;
silc_sftp_send_packet(client, req->type, len,
SILC_LOG_DEBUG(("Rmdir request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_RMDIR;
req->status = callback;
SILC_LOG_DEBUG(("Opendir request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_OPENDIR;
req->handle = callback;
SILC_LOG_DEBUG(("Readdir request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_READDIR;
req->name = callback;
SILC_LOG_DEBUG(("Stat request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_STAT;
req->attr = callback;
SILC_LOG_DEBUG(("Lstat request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_LSTAT;
req->attr = callback;
SILC_LOG_DEBUG(("Fstat request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_FSTAT;
req->attr = callback;
SILC_LOG_DEBUG(("Setstat request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_SETSTAT;
req->status = callback;
silc_list_add(client->requests, req);
attrs_buf = silc_sftp_attr_encode(attrs);
+ if (attrs_buf)
+ return;
len = 4 + 4 + strlen(path) + attrs_buf->len;
silc_sftp_send_packet(client, req->type, len,
SILC_LOG_DEBUG(("Fsetstat request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_FSETSTAT;
req->status = callback;
silc_sftp_handle_get(handle, &hdata, &hdata_len);
attrs_buf = silc_sftp_attr_encode(attrs);
+ if (attrs_buf)
+ return;
len = 4 + 4 + hdata_len + attrs_buf->len;
silc_sftp_send_packet(client, req->type, len,
SILC_LOG_DEBUG(("Readlink request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_READLINK;
req->name = callback;
SILC_LOG_DEBUG(("Symlink request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_SYMLINK;
req->status = callback;
SILC_LOG_DEBUG(("Realpath request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_REALPATH;
req->name = callback;
SILC_LOG_DEBUG(("Extended request"));
req = silc_calloc(1, sizeof(*req));
+ if (!req)
+ return;
req->id = client->id++;
req->type = SILC_SFTP_WRITE;
req->extended = callback;
if (!dir->entry) {
dir->entry = silc_calloc(3, sizeof(*entry));
+ if (!dir->entry)
+ return FALSE;
dir->entry[0] = entry;
dir->entry_count = 3;
entry->created = time(0);
dir->entry = silc_realloc(dir->entry, sizeof(*dir->entry) *
(dir->entry_count + 3));
+ if (!dir->entry)
+ return FALSE;
for (i = dir->entry_count + 1; i < dir->entry_count + 3; i++)
dir->entry[i] = NULL;
dir->entry[dir->entry_count] = entry;
int i;
handle = silc_calloc(1, sizeof(*handle));
+ if (!handle)
+ return NULL;
handle->fd = fd;
handle->entry = entry;
if (!fs->handles) {
fs->handles = silc_calloc(5, sizeof(*fs->handles));
+ if (!fs->handles)
+ return NULL;
fs->handles[0] = handle;
fs->handles_count = 5;
fs->handles = silc_realloc(fs->handles, sizeof(*fs->handles) *
(fs->handles_count + 5));
+ if (!fs->handles)
+ return NULL;
for (i = fs->handles_count + 1; i < fs->handles_count + 5; i++)
fs->handles[i] = NULL;
fs->handles[fs->handles_count] = handle;
MemFS fs;
fs = silc_calloc(1, sizeof(*fs));
+ if (!fs)
+ return NULL;
+
fs->root = silc_calloc(1, sizeof(*fs->root));
+ if (!fs->root) {
+ silc_free(fs);
+ return NULL;
+ }
+
fs->root->perm = perm;
fs->root_perm = perm;
fs->root->directory = TRUE;
fs->root->name = strdup(DIR_SEPARATOR);
filesystem = silc_calloc(1, sizeof(*filesystem));
- filesystem->fs =
- (struct SilcSFTPFilesystemOpsStruct *)&silc_sftp_fs_memory;
+ if (!filesystem) {
+ silc_free(fs->root);
+ silc_free(fs);
+ return NULL;
+ }
+
+ filesystem->fs = (struct SilcSFTPFilesystemOpsStruct *)&silc_sftp_fs_memory;
filesystem->fs_context = (void *)fs;
return filesystem;
MemFSEntry entry;
entry = silc_calloc(1, sizeof(*entry));
+ if (!entry)
+ return NULL;
+
entry->perm = perm;
entry->name = strdup(name);
entry->directory = TRUE;
ret = mem_del_entry(memfs->root, FALSE);
memfs->root = silc_calloc(1, sizeof(*memfs->root));
+ if (!memfs->root)
+ return FALSE;
+
memfs->root->perm = memfs->root_perm;
memfs->root->directory = TRUE;
memfs->root->name = strdup(DIR_SEPARATOR);
MemFSEntry entry;
entry = silc_calloc(1, sizeof(*entry));
+ if (!entry)
+ return FALSE;
+
entry->perm = perm;
entry->name = strdup(filename);
entry->data = strdup(realpath);
MemFSFileHandle h = (MemFSFileHandle)handle;
data = silc_calloc(4, sizeof(*data));
+ if (!data)
+ return NULL;
+
SILC_PUT32_MSB(h->handle, data);
*handle_len = 4;
-
return data;
}
/* File opened, return handle */
handle = mem_create_handle(fs, fd, entry);
- (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle,
- callback_context);
+ if (handle)
+ (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle,
+ callback_context);
+ else
+ (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL,
+ callback_context);
}
void mem_close(void *context, SilcSFTP sftp,
len = 32768;
data = silc_malloc(len);
+ if (!data) {
+ (*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, 0, callback_context);
+ return;
+ }
lseek(h->fd, (off_t)offset, SEEK_SET);
/* Attempt to read */
/* Directory opened, return handle */
handle = mem_create_handle(fs, 0, entry);
- (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle,
- callback_context);
+ if (handle)
+ (*callback)(sftp, SILC_SFTP_STATUS_OK, (SilcSFTPHandle)handle,
+ callback_context);
+ else
+ (*callback)(sftp, SILC_SFTP_STATUS_PERMISSION_DENIED, NULL,
+ callback_context);
}
void mem_readdir(void *context, SilcSFTP sftp,
}
name = silc_calloc(1, sizeof(*name));
+ if (!name) {
+ (*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, callback_context);
+ return;
+ }
for (i = h->fd; i < 100 + h->fd; i++) {
if (i >= h->entry->entry_count)
break;
/* Add attributes */
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs) {
+ (*callback)(sftp, SILC_SFTP_STATUS_EOF, NULL, callback_context);
+ return;
+ }
attrs->flags = (SILC_SFTP_ATTR_SIZE |
SILC_SFTP_ATTR_UIDGID);
attrs->size = filesize;
}
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs) {
+ (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context);
+ return;
+ }
attrs->flags = (SILC_SFTP_ATTR_SIZE |
SILC_SFTP_ATTR_UIDGID |
SILC_SFTP_ATTR_ACMODTIME);
}
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs) {
+ (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context);
+ return;
+ }
attrs->flags = (SILC_SFTP_ATTR_SIZE |
SILC_SFTP_ATTR_UIDGID |
SILC_SFTP_ATTR_ACMODTIME);
}
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs) {
+ (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context);
+ return;
+ }
attrs->flags = (SILC_SFTP_ATTR_SIZE |
SILC_SFTP_ATTR_UIDGID |
SILC_SFTP_ATTR_ACMODTIME);
path = (const char *)DIR_SEPARATOR;
realpath = mem_expand_path(fs->root, path);
- if (!realpath) {
- (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context);
- return;
- }
+ if (!realpath)
+ goto fail;
name = silc_calloc(1, sizeof(*name));
+ if (!name)
+ goto fail;
+
name->filename = silc_calloc(1, sizeof(*name->filename));
+ if (!name->filename)
+ goto fail;
name->filename[0] = realpath;
name->long_filename = silc_calloc(1, sizeof(*name->long_filename));
+ if (!name->long_filename)
+ goto fail;
name->long_filename[0] = realpath;
name->attrs = silc_calloc(1, sizeof(*name->attrs));
+ if (!name->attrs)
+ goto fail;
name->attrs[0] = silc_calloc(1, sizeof(*name->attrs[0]));
+ if (!name->attrs[0])
+ goto fail;
name->count = 1;
(*callback)(sftp, SILC_SFTP_STATUS_FAILURE, (const SilcSFTPName)name,
callback_context);
silc_sftp_name_free(name);
+ return;
+
+ fail:
+ (*callback)(sftp, SILC_SFTP_STATUS_FAILURE, NULL, callback_context);
}
void mem_extended(void *context, SilcSFTP sftp,
}
attr_buf = silc_sftp_attr_encode(attrs);
+ if (!attr_buf) {
+ silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id);
+ return;
+ }
silc_sftp_send_packet(server, SILC_SFTP_ATTRS, 4 + attr_buf->len,
SILC_STR_UI_INT(id),
SilcSFTPServer server;
server = silc_calloc(1, sizeof(*server));
+ if (!server)
+ return NULL;
server->send_packet = send_packet;
server->send_context = send_context;
server->fs = fs;
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
}
/* Call monitor */
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
}
/* Call monitor */
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
}
/* Call monitor */
if (attr_len) {
silc_buffer_set(&tmpbuf, attr_buf, attr_len);
attrs = silc_sftp_attr_decode(&tmpbuf);
+ if (!attrs)
+ goto failure;
} else {
attrs = silc_calloc(1, sizeof(*attrs));
+ if (!attrs)
+ goto failure;
}
/* Get the handle */
int ret;
if (packet_buf) {
- if (packet_buf->truelen < 4 + 1 + len)
+ if (packet_buf->truelen < 4 + 1 + len) {
packet_buf = silc_buffer_realloc(packet_buf, 4 + 1 + len);
+ if (!packet_buf)
+ return NULL;
+ }
buffer = packet_buf;
dyn = FALSE;
} else {
buffer = silc_buffer_alloc(4 + 1 + len);
+ if (!buffer)
+ return NULL;
dyn = TRUE;
}
}
buffer = silc_buffer_alloc(len);
+ if (!buffer)
+ return NULL;
silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
silc_buffer_format(buffer,
SilcSFTPAttributes attr;
attr = silc_calloc(1, sizeof(*attr));
+ if (!attr)
+ return NULL;
if (silc_buffer_unformat(buffer,
SILC_STR_UI_INT(&attr->flags),
sizeof(*attr->extended_type));
attr->extended_data = silc_calloc(attr->extended_count,
sizeof(*attr->extended_data));
+ if (!attr->extended_type || !attr->extended_data)
+ return NULL;
+
for (i = 0; i < attr->extended_count; i++) {
unsigned char *tmp, *tmp2;
SilcUInt32 tmp_len, tmp2_len;
attr->extended_type[i] = silc_buffer_alloc(tmp_len);
attr->extended_data[i] = silc_buffer_alloc(tmp2_len);
+ if (!attr->extended_type[i] || !attr->extended_data[i])
+ return NULL;
silc_buffer_put(attr->extended_type[i], tmp, tmp_len);
silc_buffer_put(attr->extended_data[i], tmp2, tmp2_len);
(name->count + 1));
name->attrs = silc_realloc(name->attrs, sizeof(*name->attrs) *
(name->count + 1));
+ if (!name->filename || !name->long_filename || !name->attrs)
+ return;
name->filename[name->count] = strdup(short_name);
name->long_filename[name->count] = strdup(long_name);
SilcBuffer *attr_buf;
attr_buf = silc_calloc(name->count, sizeof(*attr_buf));
+ if (!attr_buf)
+ return NULL;
+
for (i = 0; i < name->count; i++) {
len += (8 + strlen(name->filename[i]) + strlen(name->long_filename[i]));
attr_buf[i] = silc_sftp_attr_encode(name->attrs[i]);
+ if (attr_buf[i])
+ return NULL;
len += attr_buf[i]->len;
}
buffer = silc_buffer_alloc(len);
+ if (!buffer)
+ return NULL;
silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
silc_buffer_format(buffer,
int ret;
name = silc_calloc(1, sizeof(*name));
+ if (!name)
+ return NULL;
name->filename = silc_calloc(count, sizeof(*name->filename));
name->long_filename = silc_calloc(count, sizeof(*name->filename));
name->attrs = silc_calloc(count, sizeof(*name->attrs));
+ if (!name->filename || !name->long_filename || !name->attrs) {
+ silc_sftp_name_free(name);
+ return NULL;
+ }
name->count = count;
for (i = 0; i < count; i++) {
/* Decode attributes, this will pull the `buffer' to correct place
for next round automatically. */
name->attrs[i] = silc_sftp_attr_decode(buffer);
+ if (!name->attrs[i]) {
+ silc_sftp_name_free(name);
+ return NULL;
+ }
}
return name;
*
***/
typedef struct {
- SilcUInt32 flags; /* Flags to indicate present attributes */
- SilcUInt64 size; /* Sife of the file in bytes */
- SilcUInt32 uid; /* Unix user ID */
- SilcUInt32 gid; /* Unix group ID */
- SilcUInt32 permissions; /* POSIX file permission bitmask */
- SilcUInt32 atime; /* Access time of file */
- SilcUInt32 mtime; /* Modification time of file */
+ SilcUInt32 flags; /* Flags to indicate present attributes */
+ SilcUInt64 size; /* Sife of the file in bytes */
+ SilcUInt32 uid; /* Unix user ID */
+ SilcUInt32 gid; /* Unix group ID */
+ SilcUInt32 permissions; /* POSIX file permission bitmask */
+ SilcUInt32 atime; /* Access time of file */
+ SilcUInt32 mtime; /* Modification time of file */
SilcUInt32 extended_count; /* Extended type and data count */
SilcBuffer *extended_type;
* example when reading the contents of a directory.
*
***/
-typedef struct {
+typedef struct {
char **filename;
char **long_filename;
SilcSFTPAttributes *attrs;