SilcBool silc_client_attribute_del(SilcClient client, SilcClientConnection conn, SilcAttribute attribute, SilcAttributePayload attr) { SilcBool ret; if (!conn->internal->attrs) return FALSE; if (attr) { attribute = silc_attribute_get_attribute(attr); ret = silc_hash_table_del_by_context(conn->internal->attrs, SILC_32_TO_PTR(attribute), attr); } else if (attribute) { silc_hash_table_find_foreach(conn->internal->attrs, SILC_32_TO_PTR(attribute), silc_client_attribute_del_foreach, conn); ret = TRUE; } else{ return FALSE; } if (ret) if (!silc_hash_table_count(conn->internal->attrs)) { silc_hash_table_free(conn->internal->attrs); conn->internal->attrs = NULL; } return ret; }
SilcServerPending silc_server_command_pending_get(SilcServerThread thread, SilcUInt16 cmd_ident) { SilcServerPending pending = NULL; silc_mutex_lock(thread->server->lock); silc_hash_table_find(thread->server->pending_commands, SILC_32_TO_PTR(cmd_ident), NULL, (void **)&pending); silc_mutex_unlock(thread->server->lock); return pending; }
static void silc_client_attribute_del_foreach(void *key, void *context, void *user_context) { SilcClientConnection conn = user_context; SilcAttributePayload attr = context; SilcAttribute attribute; if (!attr) return; attribute = silc_attribute_get_attribute(attr); silc_hash_table_del_by_context(conn->internal->attrs, SILC_32_TO_PTR(attribute), attr); }
SilcServerPending silc_server_command_pending(SilcServerThread thread, SilcUInt16 cmd_ident) { SilcServerPending pending; silc_mutex_lock(thread->server->lock); /* Check if pending already */ if (silc_hash_table_find(thread->server->pending_commands, SILC_32_TO_PTR(cmd_ident), NULL, (void **)&pending)) { pending->refcnt++; silc_mutex_unlock(thread->server->lock); return pending; } pending = silc_calloc(1, sizeof(*pending)); if (!pending) { silc_mutex_unlock(thread->server->lock); return NULL; } silc_fsm_event_init(&pending->wait_reply, &thread->fsm, 0); pending->refcnt = 1; pending->cmd_ident = cmd_ident; /* Add to pending commands hash table */ if (!silc_hash_table_add(thread->server->pending_commands, SILC_32_TO_PTR(cmd_ident), pending)) { silc_mutex_unlock(thread->server->lock); silc_free(pending); return NULL; } silc_mutex_unlock(thread->server->lock); return pending; }
void silc_server_command_pending_signal(SilcServerCommand cmd) { SilcServerThread thread = cmd->thread; SilcServerPending pending = cmd->pending; if (!pending) return; silc_mutex_lock(thread->server->lock); /* Signal */ pending->reply = cmd; SILC_FSM_EVENT_SIGNAL(&pending->wait_reply); /* Remove from pending */ silc_hash_table_del_by_context(thread->server->pending_commands, SILC_32_TO_PTR(pending->cmd_ident), pending); silc_mutex_unlock(thread->server->lock); }
SilcAttributePayload silc_client_attribute_add(SilcClient client, SilcClientConnection conn, SilcAttribute attribute, void *object, SilcUInt32 object_size) { SilcAttributePayload attr; attr = silc_attribute_payload_alloc(attribute, SILC_ATTRIBUTE_FLAG_VALID, object, object_size); if (!attr) return NULL; if (!conn->internal->attrs) conn->internal->attrs = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL, silc_client_attribute_destruct, NULL, TRUE); silc_hash_table_add(conn->internal->attrs, SILC_32_TO_PTR(attribute), attr); return attr; }
void silc_server_command_pending_free(SilcServerThread thread, SilcServerPending pending) { silc_mutex_lock(thread->server->lock); pending->refcnt--; if (pending->refcnt > 0) { silc_mutex_unlock(thread->server->lock); return; } /* If command reply context set, free it also */ if (pending->reply) { pending->reply->pending = NULL; silc_server_command_free(pending->reply); } /* Remove from pending commands */ silc_hash_table_del_by_context(thread->server->pending_commands, SILC_32_TO_PTR(pending->cmd_ident), pending); silc_free(pending); silc_mutex_unlock(thread->server->lock); }
SilcMime silc_mime_assemble(SilcMimeAssembler assembler, SilcMime partial) { char *type, *id = NULL, *tmp; SilcHashTable f; SilcMime p, complete; int i, number, total = -1; const unsigned char *data; SilcUInt32 data_len; SilcBuffer compbuf = NULL; SILC_LOG_DEBUG(("Assembling MIME fragments")); if (!assembler || !partial) goto err; type = (char *)silc_mime_get_field(partial, "Content-Type"); if (!type) goto err; /* Get ID */ tmp = strstr(type, "id="); if (!tmp) goto err; if (strlen(tmp) <= 4) goto err; tmp += 3; if (*tmp == '"') tmp++; id = strdup(tmp); if (strchr(id, ';')) *strchr(id, ';') = '\0'; if (strrchr(id, '"')) *strrchr(id, '"') = '\0'; SILC_LOG_DEBUG(("Fragment ID %s", id)); /* Get fragment number */ tmp = strstr(type, "number="); if (!tmp) goto err; tmp = strchr(tmp, '='); if (strlen(tmp) < 2) goto err; tmp++; if (strchr(tmp, ';')) { tmp = strdup(tmp); *strchr(tmp, ';') = '\0'; number = atoi(tmp); silc_free(tmp); } else { number = atoi(tmp); } SILC_LOG_DEBUG(("Fragment number %d", number)); /* Find fragments with this ID. */ if (!silc_hash_table_find(assembler->fragments, (void *)id, NULL, (void *)&f)) { /* This is new fragment to new message. Add to hash table and return. */ f = silc_hash_table_alloc(0, silc_hash_uint, NULL, NULL, NULL, silc_mime_assemble_dest, NULL, TRUE); if (!f) goto err; silc_hash_table_add(f, SILC_32_TO_PTR(number), partial); silc_hash_table_add(assembler->fragments, id, f); return NULL; } /* Try to get total number */ tmp = strstr(type, "total="); if (tmp) { tmp = strchr(tmp, '='); if (strlen(tmp) < 2) goto err; tmp++; if (strchr(tmp, ';')) { tmp = strdup(tmp); *strchr(tmp, ';') = '\0'; total = atoi(tmp); silc_free(tmp); } else { total = atoi(tmp); } SILC_LOG_DEBUG(("Fragment total %d", total)); } /* If more fragments to come, add to hash table */ if (number != total) { silc_hash_table_add(f, SILC_32_TO_PTR(number), partial); return NULL; } silc_hash_table_add(f, SILC_32_TO_PTR(number), partial); /* Verify that we really have all the fragments */ if (silc_hash_table_count(f) < total) return NULL; /* Assemble the complete MIME message now. We get them in order from the hash table. */ for (i = 1; i <= total; i++) { if (!silc_hash_table_find(f, SILC_32_TO_PTR(i), NULL, (void *)&p)) goto err; /* The fragment is in the data portion of the partial message */ data = silc_mime_get_data(p, &data_len); if (!data) goto err; /* Assemble */ if (!compbuf) { compbuf = silc_buffer_alloc_size(data_len); if (!compbuf) goto err; silc_buffer_put(compbuf, data, data_len); } else { compbuf = silc_buffer_realloc(compbuf, silc_buffer_truelen(compbuf) + data_len); if (!compbuf) goto err; silc_buffer_put_tail(compbuf, data, data_len); silc_buffer_pull_tail(compbuf, data_len); } } /* Now parse the complete MIME message and deliver it */ complete = silc_mime_decode(NULL, (const unsigned char *)compbuf->head, silc_buffer_truelen(compbuf)); if (!complete) goto err; /* Delete the hash table entry. Destructors will free memory */ silc_hash_table_del(assembler->fragments, (void *)id); silc_free(id); silc_buffer_free(compbuf); return complete; err: silc_free(id); if (compbuf) silc_buffer_free(compbuf); silc_mime_free(partial); return NULL; }
static void silc_sftp_server_receive_process(SilcSFTP sftp, SilcBuffer buffer) { SilcSFTPServer server = (SilcSFTPServer)sftp; SilcSFTPPacket type; char *filename = NULL, *path = NULL; unsigned char *payload = NULL; SilcUInt32 payload_len; int ret; SilcBufferStruct buf; SilcUInt32 id; SilcSFTPAttributes attrs; SilcSFTPHandle handle; SilcSFTPMonitorDataStruct mdata; SILC_LOG_DEBUG(("Start")); /* Parse the packet */ type = silc_sftp_packet_decode(buffer, &payload, &payload_len); if (type <= 0) return; silc_buffer_set(&buf, payload, payload_len); memset(&mdata, 0, sizeof(mdata)); switch (type) { case SILC_SFTP_READ: { unsigned char *hdata; SilcUInt32 hdata_len; SilcUInt64 offset; SilcUInt32 len; SILC_LOG_DEBUG(("Read request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&hdata, &hdata_len), SILC_STR_UI_INT64(&offset), SILC_STR_UI_INT(&len), SILC_STR_END); if (ret < 0) goto failure; /* Get the handle */ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, (const unsigned char *)hdata, hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Read operation */ server->fs->fs->sftp_read(server->fs->fs_context, sftp, handle, offset, len, silc_sftp_server_data, SILC_32_TO_PTR(id)); /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_READ && server->monitor) { mdata.offset = offset; mdata.data_len = len; (*server->monitor)(sftp, SILC_SFTP_MONITOR_READ, &mdata, server->monitor_context); } } break; case SILC_SFTP_WRITE: { unsigned char *hdata; SilcUInt32 hdata_len; SilcUInt64 offset; unsigned char *data; SilcUInt32 data_len; SILC_LOG_DEBUG(("Read request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&hdata, &hdata_len), SILC_STR_UI_INT64(&offset), SILC_STR_UI32_NSTRING(&data, &data_len), SILC_STR_END); if (ret < 0) goto failure; /* Get the handle */ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, (const unsigned char *)hdata, hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Write operation */ server->fs->fs->sftp_write(server->fs->fs_context, sftp, handle, offset, (const unsigned char *)data, data_len, silc_sftp_server_status, SILC_32_TO_PTR(id)); /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_WRITE && server->monitor) { mdata.offset = offset; mdata.data_len = data_len; (*server->monitor)(sftp, SILC_SFTP_MONITOR_WRITE, &mdata, server->monitor_context); } } break; case SILC_SFTP_INIT: { SilcSFTPVersion version; SILC_LOG_DEBUG(("Init request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&version), SILC_STR_END); if (ret < 0) break; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_INIT && server->monitor) { mdata.version = version; (*server->monitor)(sftp, SILC_SFTP_MONITOR_INIT, &mdata, server->monitor_context); } silc_sftp_send_packet(server, SILC_SFTP_VERSION, 4, SILC_STR_UI_INT(SILC_SFTP_PROTOCOL_VERSION), SILC_STR_END); } break; case SILC_SFTP_OPEN: { SilcSFTPFileOperation pflags; unsigned char *attr_buf; SilcUInt32 attr_len = 0; SilcBufferStruct tmpbuf; SILC_LOG_DEBUG(("Open request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&filename), SILC_STR_UI_INT(&pflags), SILC_STR_UI32_NSTRING(&attr_buf, &attr_len), SILC_STR_END); if (ret < 0) goto failure; 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 (server->monitors & SILC_SFTP_MONITOR_OPEN && server->monitor) { mdata.name = filename; mdata.pflags = pflags; (*server->monitor)(sftp, SILC_SFTP_MONITOR_OPEN, &mdata, server->monitor_context); } /* Open operation */ server->fs->fs->sftp_open(server->fs->fs_context, sftp, filename, pflags, attrs, silc_sftp_server_handle, SILC_32_TO_PTR(id)); silc_free(filename); silc_sftp_attr_free(attrs); } break; case SILC_SFTP_CLOSE: { unsigned char *hdata; SilcUInt32 hdata_len; SILC_LOG_DEBUG(("Close request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&hdata, &hdata_len), SILC_STR_END); if (ret < 0) goto failure; /* Get the handle */ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, (const unsigned char *)hdata, hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_CLOSE && server->monitor) { (*server->monitor)(sftp, SILC_SFTP_MONITOR_CLOSE, &mdata, server->monitor_context); } /* Close operation */ server->fs->fs->sftp_close(server->fs->fs_context, sftp, handle, silc_sftp_server_status, SILC_32_TO_PTR(id)); } break; case SILC_SFTP_REMOVE: { SILC_LOG_DEBUG(("Remove request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&filename), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_REMOVE && server->monitor) { mdata.name = filename; (*server->monitor)(sftp, SILC_SFTP_MONITOR_REMOVE, &mdata, server->monitor_context); } /* Remove operation */ server->fs->fs->sftp_remove(server->fs->fs_context, sftp, filename, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_free(filename); } break; case SILC_SFTP_RENAME: { char *newname = NULL; SILC_LOG_DEBUG(("Rename request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&filename), SILC_STR_UI32_STRING_ALLOC(&newname), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_RENAME && server->monitor) { mdata.name = filename; mdata.name2 = newname; (*server->monitor)(sftp, SILC_SFTP_MONITOR_RENAME, &mdata, server->monitor_context); } /* Rename operation */ server->fs->fs->sftp_rename(server->fs->fs_context, sftp, filename, newname, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_free(filename); silc_free(newname); } break; case SILC_SFTP_MKDIR: { unsigned char *attr_buf; SilcUInt32 attr_len = 0; SilcBufferStruct tmpbuf; SILC_LOG_DEBUG(("Mkdir request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_UI32_NSTRING(&attr_buf, &attr_len), SILC_STR_END); if (ret < 0) goto failure; 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 (server->monitors & SILC_SFTP_MONITOR_MKDIR && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_MKDIR, &mdata, server->monitor_context); } /* Mkdir operation */ server->fs->fs->sftp_mkdir(server->fs->fs_context, sftp, path, attrs, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_sftp_attr_free(attrs); silc_free(path); } break; case SILC_SFTP_RMDIR: { SILC_LOG_DEBUG(("Rmdir request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_RMDIR && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_RMDIR, &mdata, server->monitor_context); } /* Rmdir operation */ server->fs->fs->sftp_rmdir(server->fs->fs_context, sftp, path, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_free(path); } break; case SILC_SFTP_OPENDIR: { SILC_LOG_DEBUG(("Opendir request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_OPENDIR && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_OPENDIR, &mdata, server->monitor_context); } /* Opendir operation */ server->fs->fs->sftp_opendir(server->fs->fs_context, sftp, path, silc_sftp_server_handle, SILC_32_TO_PTR(id)); silc_free(path); } break; case SILC_SFTP_READDIR: { unsigned char *hdata; SilcUInt32 hdata_len; SILC_LOG_DEBUG(("Readdir request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&hdata, &hdata_len), SILC_STR_END); if (ret < 0) goto failure; /* Get the handle */ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, (const unsigned char *)hdata, hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_READDIR && server->monitor) { (*server->monitor)(sftp, SILC_SFTP_MONITOR_READDIR, &mdata, server->monitor_context); } /* Readdir operation */ server->fs->fs->sftp_readdir(server->fs->fs_context, sftp, handle, silc_sftp_server_name, SILC_32_TO_PTR(id)); } break; case SILC_SFTP_STAT: { SILC_LOG_DEBUG(("Stat request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_STAT && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_STAT, &mdata, server->monitor_context); } /* Stat operation */ server->fs->fs->sftp_stat(server->fs->fs_context, sftp, path, silc_sftp_server_attr, SILC_32_TO_PTR(id)); silc_free(path); } break; case SILC_SFTP_LSTAT: { SILC_LOG_DEBUG(("Lstat request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_LSTAT && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_LSTAT, &mdata, server->monitor_context); } /* Lstat operation */ server->fs->fs->sftp_lstat(server->fs->fs_context, sftp, path, silc_sftp_server_attr, SILC_32_TO_PTR(id)); silc_free(path); } break; case SILC_SFTP_FSTAT: { unsigned char *hdata; SilcUInt32 hdata_len; SILC_LOG_DEBUG(("Fstat request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&hdata, &hdata_len), SILC_STR_END); if (ret < 0) goto failure; /* Get the handle */ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, (const unsigned char *)hdata, hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_FSTAT && server->monitor) { (*server->monitor)(sftp, SILC_SFTP_MONITOR_FSTAT, &mdata, server->monitor_context); } /* Fstat operation */ server->fs->fs->sftp_fstat(server->fs->fs_context, sftp, handle, silc_sftp_server_attr, SILC_32_TO_PTR(id)); } break; case SILC_SFTP_SETSTAT: { unsigned char *attr_buf; SilcUInt32 attr_len = 0; SilcBufferStruct tmpbuf; SILC_LOG_DEBUG(("Setstat request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_UI32_NSTRING(&attr_buf, &attr_len), SILC_STR_END); if (ret < 0) goto failure; 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 (server->monitors & SILC_SFTP_MONITOR_SETSTAT && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_SETSTAT, &mdata, server->monitor_context); } /* Setstat operation */ server->fs->fs->sftp_setstat(server->fs->fs_context, sftp, path, attrs, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_sftp_attr_free(attrs); silc_free(path); } break; case SILC_SFTP_FSETSTAT: { unsigned char *hdata, *attr_buf; SilcUInt32 hdata_len, attr_len = 0; SilcBufferStruct tmpbuf; SILC_LOG_DEBUG(("Fsetstat request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_NSTRING(&hdata, &hdata_len), SILC_STR_UI32_NSTRING(&attr_buf, &attr_len), SILC_STR_END); if (ret < 0) goto failure; 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 */ handle = server->fs->fs->sftp_get_handle(server->fs->fs_context, sftp, (const unsigned char *)hdata, hdata_len); if (!handle) { silc_sftp_send_error(server, SILC_SFTP_STATUS_NO_SUCH_FILE, id); break; } /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_FSETSTAT && server->monitor) { (*server->monitor)(sftp, SILC_SFTP_MONITOR_FSETSTAT, &mdata, server->monitor_context); } /* Fsetstat operation */ server->fs->fs->sftp_fsetstat(server->fs->fs_context, sftp, handle, attrs, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_sftp_attr_free(attrs); } break; case SILC_SFTP_READLINK: { SILC_LOG_DEBUG(("Readlink request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_READLINK && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_READLINK, &mdata, server->monitor_context); } /* Readlink operation */ server->fs->fs->sftp_readlink(server->fs->fs_context, sftp, path, silc_sftp_server_name, SILC_32_TO_PTR(id)); silc_free(path); } break; case SILC_SFTP_SYMLINK: { char *target = NULL; SILC_LOG_DEBUG(("Symlink request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_UI32_STRING_ALLOC(&target), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_SYMLINK && server->monitor) { mdata.name = path; mdata.name2 = target; (*server->monitor)(sftp, SILC_SFTP_MONITOR_SYMLINK, &mdata, server->monitor_context); } /* Symlink operation */ server->fs->fs->sftp_symlink(server->fs->fs_context, sftp, path, target, silc_sftp_server_status, SILC_32_TO_PTR(id)); silc_free(path); silc_free(target); } break; case SILC_SFTP_REALPATH: { SILC_LOG_DEBUG(("Realpath request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&path), SILC_STR_END); if (ret < 0) goto failure; /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_REALPATH && server->monitor) { mdata.name = path; (*server->monitor)(sftp, SILC_SFTP_MONITOR_REALPATH, &mdata, server->monitor_context); } /* Realpath operation */ server->fs->fs->sftp_realpath(server->fs->fs_context, sftp, path, silc_sftp_server_name, SILC_32_TO_PTR(id)); silc_free(path); } break; case SILC_SFTP_EXTENDED: { char *request = NULL; unsigned char *data; SilcUInt32 data_len; SILC_LOG_DEBUG(("Extended request")); ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&id), SILC_STR_UI32_STRING_ALLOC(&request), SILC_STR_END); if (ret < 0) goto failure; data_len = 8 + strlen(request); silc_buffer_pull(&buf, data_len); ret = silc_buffer_unformat(&buf, SILC_STR_DATA(&data, silc_buffer_len(&buf)), SILC_STR_END); if (ret < 0) goto failure; data_len = silc_buffer_len(&buf); /* Call monitor */ if (server->monitors & SILC_SFTP_MONITOR_EXTENDED && server->monitor) { (*server->monitor)(sftp, SILC_SFTP_MONITOR_EXTENDED, &mdata, server->monitor_context); } /* Extended operation */ server->fs->fs->sftp_extended(server->fs->fs_context, sftp, request, data, data_len, silc_sftp_server_extended, SILC_32_TO_PTR(id)); silc_free(request); } break; default: break; } return; failure: silc_sftp_send_error(server, SILC_SFTP_STATUS_FAILURE, id); }
int main(int argc, char **argv) { SilcBool success = FALSE; SilcAtomic32 ref32; SilcAtomic16 ref16; SilcAtomic8 ref8; SilcAtomicPointer refptr; SilcUInt8 ret8; SilcUInt16 ret16; SilcUInt32 ret32; if (argc > 1 && !strcmp(argv[1], "-d")) { silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_set_debug_string("*atomic*,*errno*"); } silc_atomic_init8(&ref8, 1); silc_atomic_init16(&ref16, 1); silc_atomic_init32(&ref32, 1); silc_atomic_init_pointer(&refptr, SILC_32_TO_PTR(0xdeadbeef)); ret8 = silc_atomic_add_int8(&ref8, 7); SILC_LOG_DEBUG(("ref8: 1 + 7 = %d (8)", ret8)); ret8 = silc_atomic_add_int8(&ref8, 3); SILC_LOG_DEBUG(("ref8: 8 + 3 = %d (11)", ret8)); ret8 = silc_atomic_sub_int8(&ref8, 10); SILC_LOG_DEBUG(("ref8: 11 - 10 = %d (1)", ret8)); ret16 = silc_atomic_add_int16(&ref16, 1); SILC_LOG_DEBUG(("ref16: 1 + 1 = %d (2)", ret16)); ret16 = silc_atomic_add_int16(&ref16, 31020); SILC_LOG_DEBUG(("ref16: 2 + 31020 = %d (31022)", ret16)); ret16 = silc_atomic_add_int16(&ref16, 34000); SILC_LOG_DEBUG(("ref16: 31022 + 34000 = %d (65022)", ret16)); ret16 = silc_atomic_sub_int16(&ref16, 0); SILC_LOG_DEBUG(("ref16: 65022 - 0 = %d (65022)", ret16)); ret16 = silc_atomic_sub_int16(&ref16, (SilcInt16)0xffff); SILC_LOG_DEBUG(("ref16: 65022 - 0xffff = %d (65023) (underflow)", ret16)); SILC_LOG_DEBUG(("Current value: %d (-513)", (SilcInt16)silc_atomic_get_int16(&ref16))); SILC_LOG_DEBUG(("Swapping -513 with 57392")); if (!silc_atomic_cas16(&ref16, silc_atomic_get_int16(&ref16), 57392)) goto err; SILC_LOG_DEBUG(("Current value: %d (57392)", silc_atomic_get_int16(&ref16))); SILC_LOG_DEBUG(("Swapping 57392 with -500")); if (!silc_atomic_cas16(&ref16, silc_atomic_get_int16(&ref16), -500)) goto err; SILC_LOG_DEBUG(("Current value: %d (-500)", (SilcInt16)silc_atomic_get_int16(&ref16))); ret32 = silc_atomic_add_int32(&ref32, 1); SILC_LOG_DEBUG(("ref32: 1 + 1 = %d (2)", ret32)); ret32 = silc_atomic_add_int32(&ref32, 310200); SILC_LOG_DEBUG(("ref32: 2 + 310200 = %d (310202)", ret32)); ret32 = silc_atomic_add_int32(&ref32, 34000000); SILC_LOG_DEBUG(("ref32: 310202 + 34000000 = %d (34310202)", ret32)); ret32 = silc_atomic_sub_int32(&ref32, 0); SILC_LOG_DEBUG(("ref32: 34310202 - 0 = %d (34310202)", ret32)); ret32 = silc_atomic_sub_int32(&ref32, 0xfffffff); SILC_LOG_DEBUG(("ref32: 34310202 - 0xfffffff = %d (-234125253) " "(underflow)", ret32)); SILC_LOG_DEBUG(("Current value: %d (-234125253)", silc_atomic_get_int32(&ref32))); SILC_LOG_DEBUG(("Swapping -234125253 with 76327681")); if (!silc_atomic_cas32(&ref32, silc_atomic_get_int32(&ref32), 76327681)) goto err; SILC_LOG_DEBUG(("Current value: %d (76327681)", silc_atomic_get_int32(&ref32))); SILC_LOG_DEBUG(("Current ptr: %p (0xdeadbeef)", silc_atomic_get_pointer(&refptr))); SILC_LOG_DEBUG(("Swapping %p with NULL", silc_atomic_get_pointer(&refptr))); if (!silc_atomic_cas_pointer(&refptr, silc_atomic_get_pointer(&refptr), NULL)) goto err; SILC_LOG_DEBUG(("Current ptr: %p (NULL)", silc_atomic_get_pointer(&refptr))); SILC_LOG_DEBUG(("Setting val 34322111 (32-bit)")); silc_atomic_set_int32(&ref32, 34322111); if (silc_atomic_get_int32(&ref32) != 34322111) goto err; SILC_LOG_DEBUG(("Setting val 1432211119 (32-bit)")); silc_atomic_set_int32(&ref32, 1432211119); if (silc_atomic_get_int32(&ref32) != 1432211119) goto err; SILC_LOG_DEBUG(("Setting val 23422 (16-bit)")); silc_atomic_set_int16(&ref16, 23422); if (silc_atomic_get_int16(&ref16) != 23422) goto err; SILC_LOG_DEBUG(("Setting val 124 (8-bit)")); silc_atomic_set_int8(&ref8, 124); if (silc_atomic_get_int8(&ref8) != 124) goto err; silc_atomic_uninit8(&ref8); silc_atomic_uninit16(&ref16); silc_atomic_uninit32(&ref32); silc_atomic_uninit_pointer(&refptr); success = TRUE; err: SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE")); fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE"); return !success; }
SilcBuffer silc_client_attributes_process(SilcClient client, SilcClientConnection conn, SilcDList attrs) { SilcBuffer buffer = NULL; SilcAttrForeach f; SilcAttribute attribute; SilcAttributePayload attr; SilcAttributeObjPk pk; unsigned char sign[2048 + 1]; SilcUInt32 sign_len; SILC_LOG_DEBUG(("Process Requested Attributes")); /* If nothing is set by application assume that we don't want to use attributes, ignore the request. */ if (!conn->internal->attrs) { SILC_LOG_DEBUG(("User has not set any attributes")); return NULL; } /* Always put our public key. */ pk.type = "silc-rsa"; pk.data = silc_pkcs_public_key_encode(conn->public_key, &pk.data_len); buffer = silc_attribute_payload_encode(buffer, SILC_ATTRIBUTE_USER_PUBLIC_KEY, pk.data ? SILC_ATTRIBUTE_FLAG_VALID : SILC_ATTRIBUTE_FLAG_INVALID, &pk, sizeof(pk)); silc_free(pk.data); /* Go through all requested attributes */ f.buffer = buffer; silc_dlist_start(attrs); while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) { /* Put all attributes of this type */ attribute = silc_attribute_get_attribute(attr); /* Ignore signature since we will compute it later */ if (attribute == SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE) continue; silc_hash_table_find_foreach(conn->internal->attrs, SILC_32_TO_PTR(attribute), silc_client_attributes_process_foreach, &f); } buffer = f.buffer; /* Finally compute the digital signature of all the data we provided. */ if (silc_pkcs_sign(conn->private_key, silc_buffer_data(buffer), silc_buffer_len(buffer), sign, sizeof(sign), &sign_len, TRUE, conn->internal->sha1hash)) { pk.type = NULL; pk.data = sign; pk.data_len = sign_len; buffer = silc_attribute_payload_encode(buffer, SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE, SILC_ATTRIBUTE_FLAG_VALID, &pk, sizeof(pk)); } return buffer; }