static DBusMessage * server_get_type(DBusMessage *msg) { DBusMessage *rsp = 0; char *key = 0; const char *val = 0; DBusError err = DBUS_ERROR_INIT; if( dbus_message_get_args(msg, &err, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID) ) { val = database_get_type(key, ""); } else { log_err("%s: %s: %s\n", dbus_message_get_member(msg), err.name, err.message); } rsp = server_make_reply(msg, DBUS_TYPE_STRING, &val, DBUS_TYPE_INVALID); dbus_error_free(&err); log_info("%s -> reply: '%s'\n", __FUNCTION__, val); return rsp; }
/* -------------------------------------------------------------------------- */ int server_process(server_t* server, const unsigned char* data, size_t size, unsigned char** response, size_t* response_size) { if(server == NULL || server->db == NULL || data == NULL || strlen((char*)data) == 0 || size == 0 || response == NULL || response_size == NULL) return ERROR_INVALID_ARGUMENTS; /* unpack package */ unsigned char packettype = '\0'; unsigned char *domain = NULL; unsigned char* key = NULL; data_store_t ds; if(simple_memory_buffer_new(&ds, data, size) != ERROR_OK ) return ERROR_UNKNOWN; int64_t ret = ERROR_OK; if((ret = data_store_read_byte(&ds, &packettype)) != ERROR_OK || (ret = bunpack(&ds, "ss", &domain, &key)) != ERROR_OK){ if(domain != NULL) freeMemory(domain); if(key != NULL) freeMemory(key); } /* handle incomming data */ int64_t integer = 0; double dob = 0.0; char* string = NULL; unsigned char* blob = NULL; size_t bsize = 0; database_value_type_t type; size_t count = 0; int64_t count_enum = 0; size_t esize = 0; char* keys = NULL; data_store_t response_ds; if(simple_memory_buffer_new(&response_ds, NULL, 0) != ERROR_OK){ if(domain != NULL) freeMemory(domain); if(key != NULL) freeMemory(key); simple_memory_buffer_free(&ds); return ERROR_UNKNOWN; } if(ret == ERROR_OK){ switch(packettype){ /* Int handling */ case PACKET_GET_INT: ret = database_get_int64(server->db, (char*)domain, (char*)key, &integer); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_INT) != ERROR_OK || bpack(&response_ds, "l", integer) != ERROR_OK) ret = ERROR_UNKNOWN; break; case PACKET_SET_INT: if(bunpack(&ds, "l", &integer) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_int64(server->db, (char*)domain, (char*)key, integer); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* Double handling */ case PACKET_GET_DOUBLE: ret = database_get_double(server->db, (char*)domain, (char*)key, &dob); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_DOUBLE) != ERROR_OK || bpack(&response_ds, "d", dob) != ERROR_OK) ret = ERROR_UNKNOWN; break; case PACKET_SET_DOUBLE: if(bunpack(&ds, "d", &dob) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_double(server->db, (char*)domain, (char*)key, dob); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* String handling */ case PACKET_GET_STRING: ret = database_get_string(server->db, (char*)domain, (char*)key, &string); if(ret != ERROR_OK){ if(string) freeMemory(string); break; } if(data_store_write_byte(&response_ds, PACKET_STRING) != ERROR_OK || bpack(&response_ds, "s", string) != ERROR_OK) ret = ERROR_UNKNOWN; freeMemory(string); break; case PACKET_SET_STRING: if(bunpack(&ds, "s", &string) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_string(server->db, (char*)domain, (char*)key, string); if(ret != ERROR_OK) break; freeMemory(string); if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* Blob handling */ case PACKET_GET_BLOB: ret = database_get_blob(server->db, (char*)domain, (char*)key, &blob, &bsize); if(ret != ERROR_OK){ if(blob != NULL) freeMemory(blob); break; } if(data_store_write_byte(&response_ds, PACKET_BLOB) != ERROR_OK || bpack(&response_ds, "b", bsize, blob) != ERROR_OK) ret = ERROR_UNKNOWN; freeMemory(blob); break; case PACKET_SET_BLOB: if(bunpack(&ds, "b", &bsize, &blob) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = database_set_blob(server->db, (char*)domain, (char*)key, blob, bsize); if(ret != ERROR_OK) break; freeMemory(blob); if(data_store_write_byte(&response_ds, PACKET_OK) != ERROR_OK) ret = ERROR_UNKNOWN; break; /* Others handling */ case PACKET_GET_ENUM: ret = database_enum_keys(server->db, (char*)domain, (char*)key, &count, &esize, &keys); if(ret != ERROR_OK){ if(keys != NULL) freeMemory(keys); break; } count_enum = count; if(data_store_write_byte(&response_ds, PACKET_ENUM) != ERROR_OK) ret = ERROR_UNKNOWN; if(keys == NULL){ if(bpack(&response_ds, "l", count_enum) != ERROR_OK) ret = ERROR_UNKNOWN; }else{ if(bpack(&response_ds, "lb", count_enum, esize, keys) != ERROR_OK) ret = ERROR_UNKNOWN; freeMemory(keys); } break; case PACKET_GET_VALUE_TYPE: ret = database_get_type(server->db, (char*)domain, (char*)key, &type); if(ret != ERROR_OK) break; if(data_store_write_byte(&response_ds, PACKET_TYPE) != ERROR_OK || bpack(&response_ds, "l", (int64_t)type) != ERROR_OK) ret = ERROR_UNKNOWN; break; case PACKET_SHUTDOWN: if(server_shutdown(server) != ERROR_OK){ ret = ERROR_UNKNOWN; break; } ret = ERROR_SERVER_SHUTDOWN; break; default: ret = ERROR_UNKNOWN; break; } freeMemory(domain); freeMemory(key); } /* free input datastore */ if(simple_memory_buffer_free(&ds) != ERROR_OK) ret = ERROR_UNKNOWN; /* send packet */ if(ret == ERROR_OK){ if(sendPacket(&response_ds, response_size, response) != ERROR_OK) ret = ERROR_UNKNOWN; } if(simple_memory_buffer_free(&response_ds) != ERROR_OK) ret = ERROR_UNKNOWN; /* error packet */ if(ret != ERROR_OK && ret != ERROR_SERVER_SHUTDOWN){ data_store_t error_ds; if(simple_memory_buffer_new(&error_ds, NULL, 0) != ERROR_OK || data_store_write_byte(&error_ds, PACKET_ERROR) != ERROR_OK || bpack(&error_ds, "l", ret) != ERROR_OK){ simple_memory_buffer_free(&error_ds); ret = ERROR_UNKNOWN; }else{ if((ret = sendPacket(&error_ds, response_size, response)) != ERROR_OK) ret = ERROR_UNKNOWN; simple_memory_buffer_free(&error_ds); } } return ret; }