diff --git a/example-clients/property.c b/example-clients/property.c new file mode 100644 index 00000000..26245e26 --- /dev/null +++ b/example-clients/property.c @@ -0,0 +1,336 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static int subject_is_client = 0; +static int subject_is_port = 0; +static jack_uuid_t uuid; +static char* subject; + +static void +show_usage (void) +{ + fprintf (stderr, "\nUsage: jack_property [options] UUID [ key [ value [ type ] ] ]\n"); + fprintf (stderr, "Set/Display JACK properties (metadata).\n\n"); + fprintf (stderr, "Set options:\n"); + fprintf (stderr, " -s, --set Set property \"key\" to \"value\" for \"UUID\" with optional MIME type \"type\"\n"); + fprintf (stderr, " -d, --delete Remove/delete property \"key\" for \"UUID\"\n"); + fprintf (stderr, " -d, --delete UUID Remove/delete all properties for \"UUID\"\n"); + fprintf (stderr, " -D, --delete-all Remove/delete all properties\n"); + fprintf (stderr, " --client Interpret UUID as a client name, not a UUID\n"); + fprintf (stderr, " --port \tInterpret UUID as a port name, not a UUID\n"); + fprintf (stderr, "\nDisplay options:\n"); + fprintf (stderr, " -l Show all properties\n"); + fprintf (stderr, " -l, --list UUID \tShow value all properties of UUID\n"); + fprintf (stderr, " -l, --list UUID key Show value for key of UUID\n"); + fprintf (stderr, "\nFor more information see http://jackaudio.org/\n"); +} + +static int +get_subject (jack_client_t* client, char* argv[], int* optind) +{ + if (subject_is_client) { + char* cstr = argv[(*optind)++]; + char* ustr; + + if ((ustr = jack_get_uuid_for_client_name (client, cstr)) == NULL) { + fprintf (stderr, "cannot get UUID for client named %s\n", cstr); + return -1; + } + + if (jack_uuid_parse (ustr, &uuid)) { + fprintf (stderr, "cannot parse client UUID as UUID\n"); + return -1; + } + + subject = cstr; + + } else if (subject_is_port) { + + char* pstr = argv[(*optind)++]; + jack_port_t* port; + + if ((port = jack_port_by_name (client, pstr)) == NULL) { + fprintf (stderr, "cannot find port name %s\n", pstr); + return -1; + } + + uuid = jack_port_uuid (port); + subject = pstr; + + } else { + char* str = argv[(*optind)++]; + + if (jack_uuid_parse (str, &uuid)) { + fprintf (stderr, "cannot parse subject as UUID\n"); + return -1; + } + + subject = str; + } + + return 0; +} + +int main (int argc, char* argv[]) +{ + jack_client_t* client = NULL; + jack_options_t options = JackNoStartServer; + char* key = NULL; + char* value = NULL; + char* type = NULL; + int set = 1; + int delete = 0; + int delete_all = 0; + int list_all = 0; + int c; + int option_index; + extern int optind; + struct option long_options[] = { + { "set", 0, 0, 's' }, + { "delete", 0, 0, 'd' }, + { "delete-all", 0, 0, 'D' }, + { "list", 0, 0, 'l' }, + { "all", 0, 0, 'a' }, + { "client", 0, 0, 'c' }, + { "port", 0, 0, 'p' }, + { 0, 0, 0, 0 } + }; + + if (argc < 2) { + show_usage (); + exit (1); + } + + while ((c = getopt_long (argc, argv, "sdDlaApc", long_options, &option_index)) >= 0) { + switch (c) { + case 's': + if (argc < 5) { + show_usage (); + exit (1); + } + set = 1; + break; + case 'd': + if (argc < 3) { + show_usage (); + return 1; + } + set = 0; + delete = 1; + break; + + case 'D': + delete = 0; + set = 0; + delete_all = 1; + break; + + case 'l': + set = 0; + delete = 0; + delete_all = 0; + break; + + case 'a': + list_all = 1; + set = 0; + delete = 0; + delete_all = 0; + break; + + case 'p': + subject_is_port = 1; + break; + + case 'c': + subject_is_client = 1; + break; + + case '?': + default: + show_usage (); + exit (1); + } + } + + if ((client = jack_client_open ("jack-property", options, NULL)) == 0) { + fprintf (stderr, "Cannot connect to JACK server\n"); + exit (1); + } + + if (delete_all) { + + if (jack_remove_all_properties (client) == 0) { + printf ("JACK metadata successfully delete\n"); + exit (0); + } + exit (1); + } + + if (delete) { + + int args_left = argc - optind; + + if (args_left < 1) { + show_usage (); + exit (1); + } + + /* argc == 3: delete all properties for a subject + argc == 4: delete value of key for subject + */ + + if (args_left >= 2) { + + if (get_subject (client, argv, &optind)) { + return 1; + } + + key = argv[optind++]; + + if (jack_remove_property (client, uuid, key)) { + fprintf (stderr, "\"%s\" property not removed for %s\n", key, subject); + exit (1); + } + + } else { + + if (get_subject (client, argv, &optind)) { + return 1; + } + + if (jack_remove_properties (client, uuid) < 0) { + fprintf (stderr, "cannot remove properties for UUID %s\n", subject); + exit (1); + } + } + + } else if (set) { + + int args_left = argc - optind; + + if (get_subject (client, argv, &optind)) { + return -1; + } + + key = argv[optind++]; + value = argv[optind++]; + + if (args_left >= 3) { + type = argv[optind++]; + } else { + type = ""; + } + + if (jack_set_property (client, uuid, key, value, type)) { + fprintf (stderr, "cannot set value for key %s of %s\n", value, subject); + exit (1); + } + + } else { + + /* list properties */ + + int args_left = argc - optind; + + if (args_left >= 2) { + + /* list properties for a UUID/key pair */ + + if (get_subject (client, argv, &optind)) { + return -1; + } + + key = argv[optind++]; + + if (jack_get_property (uuid, key, &value, &type) == 0) { + printf ("%s\n", value); + free (value); + if (type) { + free (type); + } + } else { + fprintf (stderr, "Value not found for %s of %s\n", key, subject); + exit (1); + } + + } else if (args_left == 1) { + + /* list all properties for a given UUID */ + + jack_description_t description; + size_t cnt, n; + + if (get_subject (client, argv, &optind)) { + return -1; + } + + if ((cnt = jack_get_properties (uuid, &description)) < 0) { + fprintf (stderr, "could not retrieve properties for %s\n", subject); + exit (1); + } + + for (n = 0; n < cnt; ++n) { + if (description.properties[n].type) { + printf ("key: %s value: %s type: %s\n", + description.properties[n].key, + description.properties[n].data, + description.properties[n].type); + } else { + printf ("key: %s value: %s\n", + description.properties[n].key, + description.properties[n].data); + } + } + + jack_free_description (&description, 0); + + } else { + + /* list all properties */ + + jack_description_t* description; + size_t cnt; + size_t p; + size_t n; + char buf[JACK_UUID_STRING_SIZE]; + + if ((cnt = jack_get_all_properties (&description)) < 0) { + fprintf (stderr, "could not retrieve properties for %s\n", subject); + exit (1); + } + + for (n = 0; n < cnt; ++n) { + jack_uuid_unparse (description[n].subject, buf); + printf ("%s\n", buf); + for (p = 0; p < description[n].property_cnt; ++p) { + if (description[n].properties[p].type) { + printf ("key: %s value: %s type: %s\n", + description[n].properties[p].key, + description[n].properties[p].data, + description[n].properties[p].type); + } else { + printf ("key: %s value: %s\n", + description[n].properties[p].key, + description[n].properties[p].data); + } + } + jack_free_description (&description[n], 0); + } + + free (description); + } + } + + + (void) jack_client_close (client); + return 0; +} diff --git a/example-clients/wscript b/example-clients/wscript index c5ddb02f..341aa4c8 100644 --- a/example-clients/wscript +++ b/example-clients/wscript @@ -29,7 +29,8 @@ example_programs = { 'jack_latent_client' : 'latent_client.c', 'jack_midi_dump' : 'midi_dump.c', 'jack_midi_latency_test' : 'midi_latency_test.c', - 'jack_simdtests' : 'simdtests.cpp' + 'jack_simdtests' : 'simdtests.cpp', + 'jack_property' : 'property.c', } example_libs = {