Skip to content
This repository has been archived by the owner on Aug 5, 2022. It is now read-only.

Commit

Permalink
libbuxton: Add functionnality of getting labels
Browse files Browse the repository at this point in the history
Signed-off-by: José Bollo <[email protected]>
  • Loading branch information
José Bollo authored and bryteise committed Nov 8, 2014
1 parent 362b8b8 commit dd23004
Show file tree
Hide file tree
Showing 12 changed files with 607 additions and 9 deletions.
63 changes: 61 additions & 2 deletions src/cli/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,71 @@ bool cli_remove_group(BuxtonControl *control, BuxtonDataType type,
return ret;
}

void get_label_callback(BuxtonResponse response, void *data)
{
void **r = data;

*r = NULL;
if (buxton_response_status(response) != 0) {
return;
}

if (buxton_response_value_type(response) != BUXTON_TYPE_STRING) {
return;
}

*r = buxton_response_value(response);
}

bool cli_get_label(BuxtonControl *control, BuxtonDataType type,
char *one, char *two, char *three,
__attribute__((unused)) char *four)
{
/* Not yet implemented */
return false;
BuxtonKey key;
_cleanup_free_ char *label = NULL;
char *layer = one;
char *group = two;
char *name = three;


BuxtonData ddata;
BuxtonString dlabel;
bool ret = false;

if (!layer || !group) {
return false;
}

key = buxton_key_create(group, name, layer, type);
if (!key) {
return false;
}

if (control->client.direct) {
ddata.type = BUXTON_TYPE_UNSET;
dlabel.value = NULL;
ret = buxton_direct_get_value_for_layer(control, key,
&ddata, &dlabel,
NULL);
if (ddata.type == BUXTON_TYPE_STRING) {
free(ddata.store.d_string.value);
}
label = dlabel.value;
} else {
ret = buxton_get_label(&control->client,
key,
get_label_callback,
&label, true);
}
if (ret) {
printf("Requested key not found in layer \'%s\': %s:%s\n",
layer, group, name);
return false;
}

printf("[%s] %s:%s - %s\n", layer, group, name, label);

return true;
}

bool cli_set_value(BuxtonControl *control, BuxtonDataType type,
Expand Down
2 changes: 1 addition & 1 deletion src/cli/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ bool cli_remove_group(BuxtonControl *control,
* @param type Type of label being sought (unused)
* @param one Layer of the label being sought
* @param two Group of the label being sought
* @param two Name of the label being sought
* @param two Name of the label being sought (optional)
* @param four NULL (unused)
* @returns bool indicating success or failure
*/
Expand Down
7 changes: 5 additions & 2 deletions src/cli/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ int main(int argc, char **argv)
Command c_get_float, c_set_float;
Command c_get_double, c_set_double;
Command c_get_bool, c_set_bool;
Command c_set_label;
Command c_get_label, c_set_label;
Command c_create_group, c_remove_group;
Command c_unset_value;
Command c_create_db;
Expand Down Expand Up @@ -193,9 +193,12 @@ int main(int argc, char **argv)
hashmap_put(commands, c_set_bool.name, &c_set_bool);

/* SMACK labels */
c_get_label = (Command) { "get-label", "Get a value's label",
2, 3, "layer group [name]", &cli_get_label, BUXTON_TYPE_UNSET };
hashmap_put(commands, c_get_label.name, &c_get_label);

c_set_label = (Command) { "set-label", "Set a value's label",
3, 4, "layer group [name] label", &cli_set_label, BUXTON_TYPE_UNSET };

hashmap_put(commands, c_set_label.name, &c_set_label);

/* Group management */
Expand Down
90 changes: 90 additions & 0 deletions src/core/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,27 @@ bool parse_list(BuxtonControlMessage msg, size_t count, BuxtonData *list,
return false;
}
break;
case BUXTON_CONTROL_GET_LABEL:
if (count == 3) {
if (list[0].type != BUXTON_TYPE_STRING || list[1].type != BUXTON_TYPE_STRING ||
list[2].type != BUXTON_TYPE_STRING) {
return false;
}
key->type = BUXTON_TYPE_UNSET;
key->layer = list[0].store.d_string;
key->group = list[1].store.d_string;
key->name = list[2].store.d_string;
} else if (count == 2) {
if (list[0].type != BUXTON_TYPE_STRING || list[1].type != BUXTON_TYPE_STRING) {
return false;
}
key->type = BUXTON_TYPE_UNSET;
key->layer = list[0].store.d_string;
key->group = list[1].store.d_string;
} else {
return false;
}
break;
case BUXTON_CONTROL_LIST:
return false;
if (count != 1) {
Expand Down Expand Up @@ -227,6 +248,9 @@ bool buxtond_handle_message(BuxtonDaemon *self, client_list_item *client, size_t
case BUXTON_CONTROL_GET:
data = get_value(self, client, &key, &response);
break;
case BUXTON_CONTROL_GET_LABEL:
data = get_label(self, client, &key, &response);
break;
case BUXTON_CONTROL_UNSET:
unset_value(self, client, &key, &response);
break;
Expand Down Expand Up @@ -320,6 +344,21 @@ bool buxtond_handle_message(BuxtonDaemon *self, client_list_item *client, size_t
abort();
}
break;
case BUXTON_CONTROL_GET_LABEL:
if (data && !buxton_array_add(out_list, data)) {
abort();
}
response_len = buxton_serialize_message(&response_store,
BUXTON_CONTROL_STATUS,
msgid, out_list);
if (response_len == 0) {
if (errno == ENOMEM) {
abort();
}
buxton_log("Failed to serialize get_label response message\n");
abort();
}
break;
case BUXTON_CONTROL_UNSET:
response_len = buxton_serialize_message(&response_store,
BUXTON_CONTROL_STATUS,
Expand Down Expand Up @@ -718,6 +757,57 @@ BuxtonData *get_value(BuxtonDaemon *self, client_list_item *client,
return data;
}

BuxtonData *get_label(BuxtonDaemon *self, client_list_item *client,
_BuxtonKey *key, int32_t *status)
{
BuxtonData *data = NULL;
BuxtonString label = { NULL, 0 };
int32_t ret;

assert(self);
assert(client);
assert(key);
assert(status);

*status = -1;

data = malloc0(sizeof(BuxtonData));
if (!data) {
abort();
}

buxton_debug("Daemon getting label on [%s][%s][%s]\n",
key->layer.value,
key->group.value,
key->name.value);

self->buxton.client.uid = client->cred.uid;

ret = buxton_direct_get_value(&self->buxton, key, data, &label,
client->smack_label);
if (ret) {
goto fail;
}

if (data->type == BUXTON_TYPE_STRING) {
free(data->store.d_string.value);
}
data->type = BUXTON_TYPE_STRING;
data->store.d_string = label;
buxton_debug("get label returned successfully from db\n");

*status = 0;
goto end;
fail:
buxton_debug("get label failed\n");
free(data);
free(label.value);
data = NULL;
end:

return data;
}

BuxtonArray *list_keys(BuxtonDaemon *self, client_list_item *client,
BuxtonString *layer, int32_t *status)
{
Expand Down
12 changes: 12 additions & 0 deletions src/core/daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,18 @@ BuxtonData *get_value(BuxtonDaemon *self, client_list_item *client,
_BuxtonKey *key, int32_t *status)
__attribute__((warn_unused_result));

/**
* Buxton daemon function for getting a label
* @param self buxtond instance being run
* @param client Used to validate smack access
* @param key Key for the value being sought
* @param status Will be set with the int32_t result of the operation
* @returns BuxtonData Label stored for key if successful otherwise NULL
*/
BuxtonData *get_label(BuxtonDaemon *self, client_list_item *client,
_BuxtonKey *key, int32_t *status)
__attribute__((warn_unused_result));

/**
* Buxton daemon function for unsetting a value
* @param self buxtond instance being run
Expand Down
17 changes: 17 additions & 0 deletions src/include/buxton.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ typedef enum BuxtonControlMessage {
BUXTON_CONTROL_NOTIFY, /**<Register for notification */
BUXTON_CONTROL_UNNOTIFY, /**<Opt out of notifications */
BUXTON_CONTROL_CHANGED, /**<A key changed in Buxton */
BUXTON_CONTROL_GET_LABEL, /**<Get a label from Buxton */
BUXTON_CONTROL_MAX
} BuxtonControlMessage;

Expand Down Expand Up @@ -212,6 +213,22 @@ _bx_export_ int buxton_get_value(BuxtonClient client,
bool sync)
__attribute__((warn_unused_result));

/**
* Retrieve a label from Buxton
* @param client An open client connection
* @param key The key or group to retrieve
* @param callback A callback function to handle daemon reply
* @param data User data to be used with callback function
* @param sync Indicator for running a synchronous request
* @return An int value, indicating success of the operation
*/
_bx_export_ int buxton_get_label(BuxtonClient client,
BuxtonKey key,
BuxtonCallback callback,
void *data,
bool sync)
__attribute__((warn_unused_result));

/**
* List all keys within a given layer in Buxon
* @param client An open client connection
Expand Down
37 changes: 35 additions & 2 deletions src/libbuxton/lbuxton.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,39 @@ int buxton_set_label(BuxtonClient client,
return ret;
}

int buxton_get_label(BuxtonClient client,
BuxtonKey key,
BuxtonCallback callback,
void *data,
bool sync)
{
bool r;
int ret = 0;
_BuxtonKey *k = (_BuxtonKey *)key;

if (!k || !k->group.value || !k->layer.value ||
k->type <= BUXTON_TYPE_MIN || k->type >= BUXTON_TYPE_MAX) {
return EINVAL;
}

k->type = BUXTON_TYPE_UNSET;
r = buxton_wire_get_label((_BuxtonClient *)client, k, callback, data);
if (!r) {
return -1;
}

if (sync) {
ret = buxton_wire_get_response(client);
if (ret <= 0) {
ret = -1;
} else {
ret = 0;
}
}

return ret;
}

int buxton_create_group(BuxtonClient client,
BuxtonKey key,
BuxtonCallback callback,
Expand Down Expand Up @@ -657,7 +690,7 @@ void *buxton_response_value(BuxtonResponse response)
}

type = buxton_response_type(response);
if (type == BUXTON_CONTROL_GET) {
if (type == BUXTON_CONTROL_GET || type == BUXTON_CONTROL_GET_LABEL) {
d = buxton_array_get(r->data, 1);
} else if (type == BUXTON_CONTROL_CHANGED) {
if (r->data->len) {
Expand Down Expand Up @@ -742,7 +775,7 @@ BuxtonDataType buxton_response_value_type(BuxtonResponse response)
}

type = buxton_response_type(response);
if (type == BUXTON_CONTROL_GET) {
if (type == BUXTON_CONTROL_GET || type == BUXTON_CONTROL_GET_LABEL) {
d = buxton_array_get(r->data, 1);
} else if (type == BUXTON_CONTROL_CHANGED) {
if (r->data->len) {
Expand Down
1 change: 1 addition & 0 deletions src/libbuxton/lbuxton.sym
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ BUXTON_1 {
buxton_create_group;
buxton_remove_group;
buxton_get_value;
buxton_get_label;
buxton_unset_value;
buxton_register_notification;
buxton_unregister_notification;
Expand Down
53 changes: 53 additions & 0 deletions src/shared/protocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,59 @@ bool buxton_wire_get_value(_BuxtonClient *client, _BuxtonKey *key,
return ret;
}

bool buxton_wire_get_label(_BuxtonClient *client, _BuxtonKey *key,
BuxtonCallback callback, void *data)
{
assert(client);
assert(key);

_cleanup_free_ uint8_t *send = NULL;
bool ret = false;
size_t send_len = 0;
BuxtonArray *list = NULL;
BuxtonData d_layer;
BuxtonData d_group;
BuxtonData d_name;
uint32_t msgid = get_msgid();

buxton_string_to_data(&key->layer, &d_layer);
buxton_string_to_data(&key->group, &d_group);

list = buxton_array_new();
if (!buxton_array_add(list, &d_layer)) {
buxton_log("Failed to add layer to get_label array\n");
goto end;
}
if (!buxton_array_add(list, &d_group)) {
buxton_log("Failed to add group to get_label array\n");
goto end;
}
if (key->name.value) {
buxton_string_to_data(&key->name, &d_name);
if (!buxton_array_add(list, &d_name)) {
buxton_log("Failed to add name to get_label array\n");
goto end;
}
}

send_len = buxton_serialize_message(&send, BUXTON_CONTROL_GET_LABEL, msgid, list);

if (send_len == 0) {
goto end;
}

if (!send_message(client, send, send_len, callback, data, msgid,
BUXTON_CONTROL_GET_LABEL, key)) {
goto end;
}

ret = true;

end:
buxton_array_free(&list, NULL);
return ret;
}

bool buxton_wire_unset_value(_BuxtonClient *client,
_BuxtonKey *key,
BuxtonCallback callback,
Expand Down
Loading

0 comments on commit dd23004

Please sign in to comment.