mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-08 23:15:41 +01:00
Rewritten for the new sequencer API (with encapsulation).
This commit is contained in:
parent
e6a4296b79
commit
c7ed13b3ae
2 changed files with 127 additions and 210 deletions
|
@ -53,107 +53,81 @@ static void usage(void)
|
||||||
fprintf(stderr, " -e,--exclusive exclusive connection\n");
|
fprintf(stderr, " -e,--exclusive exclusive connection\n");
|
||||||
fprintf(stderr, " -r,--real # convert real-time-stamp on queue\n");
|
fprintf(stderr, " -r,--real # convert real-time-stamp on queue\n");
|
||||||
fprintf(stderr, " -t,--tick # convert tick-time-stamp on queue\n");
|
fprintf(stderr, " -t,--tick # convert tick-time-stamp on queue\n");
|
||||||
fprintf(stderr, " -g,--group name set the group name\n");
|
|
||||||
fprintf(stderr, " * List connected ports (no subscription action)\n");
|
fprintf(stderr, " * List connected ports (no subscription action)\n");
|
||||||
fprintf(stderr, " aconnect -i|-o [-options]\n");
|
fprintf(stderr, " aconnect -i|-o [-options]\n");
|
||||||
fprintf(stderr, " -i,--input list input (readable) ports\n");
|
fprintf(stderr, " -i,--input list input (readable) ports\n");
|
||||||
fprintf(stderr, " -o,--output list output (writable) ports\n");
|
fprintf(stderr, " -o,--output list output (writable) ports\n");
|
||||||
fprintf(stderr, " -g,--group name specify the group name\n");
|
|
||||||
fprintf(stderr, " -l,--list list current connections of each port\n");
|
fprintf(stderr, " -l,--list list current connections of each port\n");
|
||||||
fprintf(stderr, " * Remove all exported connections\n");
|
fprintf(stderr, " * Remove all exported connections\n");
|
||||||
fprintf(stderr, " -x, --removeall\n");
|
fprintf(stderr, " -x, --removeall\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* parse command line to client:port
|
|
||||||
* NB: the given string will be broken.
|
|
||||||
*/
|
|
||||||
static int parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, char *arg)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
int client, port;
|
|
||||||
|
|
||||||
if ((p = strpbrk(arg, ":.")) == NULL)
|
|
||||||
return -1;
|
|
||||||
if ((port = atoi(p + 1)) < 0)
|
|
||||||
return -1;
|
|
||||||
addr->port = port;
|
|
||||||
if (isdigit(*arg)) {
|
|
||||||
client = atoi(arg);
|
|
||||||
if (client < 0)
|
|
||||||
return -1;
|
|
||||||
addr->client = client;
|
|
||||||
} else {
|
|
||||||
/* convert from the name */
|
|
||||||
snd_seq_client_info_t cinfo;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
*p = 0;
|
|
||||||
len = strlen(arg);
|
|
||||||
if (len <= 0)
|
|
||||||
return -1;
|
|
||||||
cinfo.client = -1;
|
|
||||||
while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
|
|
||||||
if (! strncmp(cinfo.name, arg, len)) {
|
|
||||||
addr->client = cinfo.client;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1; /* not found */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check permission (capability) of specified port
|
* check permission (capability) of specified port
|
||||||
*/
|
*/
|
||||||
static int check_permission(snd_seq_port_info_t *pinfo, char *group, int perm)
|
|
||||||
|
#define LIST_INPUT 1
|
||||||
|
#define LIST_OUTPUT 2
|
||||||
|
|
||||||
|
#define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits))
|
||||||
|
|
||||||
|
static int check_permission(snd_seq_port_info_t *pinfo, int perm)
|
||||||
{
|
{
|
||||||
if ((pinfo->capability & perm) == perm &&
|
if (perm) {
|
||||||
! (pinfo->capability & SND_SEQ_PORT_CAP_NO_EXPORT))
|
if (perm & LIST_INPUT) {
|
||||||
return 1;
|
if (perm_ok(pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ))
|
||||||
if (*group && (pinfo->cap_group & perm) == perm &&
|
goto __ok;
|
||||||
! (pinfo->cap_group & SND_SEQ_PORT_CAP_NO_EXPORT))
|
}
|
||||||
return 1;
|
if (perm & LIST_OUTPUT) {
|
||||||
return 0;
|
if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE))
|
||||||
|
goto __ok;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
__ok:
|
||||||
|
if (snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* list subscribers of specified type
|
* list subscribers of specified type
|
||||||
*/
|
*/
|
||||||
static void list_each_subs(snd_seq_t *seq, snd_seq_query_subs_t *subs, int type, char *msg)
|
static void list_each_subs(snd_seq_t *seq, snd_seq_query_subscribe_t *subs, int type, const char *msg)
|
||||||
{
|
{
|
||||||
subs->type = type;
|
int count = 0;
|
||||||
subs->index = 0;
|
snd_seq_query_subscribe_set_type(subs, type);
|
||||||
|
snd_seq_query_subscribe_set_index(subs, 0);
|
||||||
while (snd_seq_query_port_subscribers(seq, subs) >= 0) {
|
while (snd_seq_query_port_subscribers(seq, subs) >= 0) {
|
||||||
if (subs->index == 0)
|
const snd_seq_addr_t *addr;
|
||||||
|
if (count++ == 0)
|
||||||
printf("\t%s: ", msg);
|
printf("\t%s: ", msg);
|
||||||
else
|
else
|
||||||
printf(", ");
|
printf(", ");
|
||||||
printf("%d:%d", subs->addr.client, subs->addr.port);
|
addr = snd_seq_query_subscribe_get_addr(subs);
|
||||||
if (subs->exclusive)
|
printf("%d:%d", addr->client, addr->port);
|
||||||
|
if (snd_seq_query_subscribe_get_exclusive(subs))
|
||||||
printf("[ex]");
|
printf("[ex]");
|
||||||
if (subs->convert_time)
|
if (snd_seq_query_subscribe_get_time_update(subs))
|
||||||
printf("[%s:%d]",
|
printf("[%s:%d]",
|
||||||
(subs->realtime ? "real" : "tick"),
|
(snd_seq_query_subscribe_get_time_real(subs) ? "real" : "tick"),
|
||||||
subs->queue);
|
snd_seq_query_subscribe_get_queue(subs));
|
||||||
subs->index++;
|
snd_seq_query_subscribe_set_index(subs, snd_seq_query_subscribe_get_index(subs) + 1);
|
||||||
}
|
}
|
||||||
if (subs->index)
|
if (count > 0)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* list subscribers
|
* list subscribers
|
||||||
*/
|
*/
|
||||||
static void list_subscribers(snd_seq_t *seq, int client, int port)
|
static void list_subscribers(snd_seq_t *seq, const snd_seq_addr_t *addr)
|
||||||
{
|
{
|
||||||
snd_seq_query_subs_t subs;
|
snd_seq_query_subscribe_t *subs;
|
||||||
memset(&subs, 0, sizeof(subs));
|
snd_seq_query_subscribe_alloca(&subs);
|
||||||
subs.client = client;
|
snd_seq_query_subscribe_set_root(subs, addr);
|
||||||
subs.port = port;
|
list_each_subs(seq, subs, SND_SEQ_QUERY_SUBS_READ, "Connecting To");
|
||||||
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_READ, "Connecting To");
|
list_each_subs(seq, subs, SND_SEQ_QUERY_SUBS_WRITE, "Connected From");
|
||||||
list_each_subs(seq, &subs, SND_SEQ_QUERY_SUBS_WRITE, "Connected From");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -161,23 +135,23 @@ static void list_subscribers(snd_seq_t *seq, int client, int port)
|
||||||
*/
|
*/
|
||||||
typedef void (*action_func_t)(snd_seq_t *seq, snd_seq_client_info_t *cinfo, snd_seq_port_info_t *pinfo, int count);
|
typedef void (*action_func_t)(snd_seq_t *seq, snd_seq_client_info_t *cinfo, snd_seq_port_info_t *pinfo, int count);
|
||||||
|
|
||||||
static void do_search_port(snd_seq_t *seq, char *group, int perm, action_func_t do_action)
|
static void do_search_port(snd_seq_t *seq, int perm, action_func_t do_action)
|
||||||
{
|
{
|
||||||
snd_seq_client_info_t cinfo;
|
snd_seq_client_info_t *cinfo;
|
||||||
snd_seq_port_info_t pinfo;
|
snd_seq_port_info_t *pinfo;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
cinfo.client = -1;
|
snd_seq_client_info_alloca(&cinfo);
|
||||||
while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
|
snd_seq_port_info_alloca(&pinfo);
|
||||||
|
snd_seq_client_info_set_client(cinfo, -1);
|
||||||
|
while (snd_seq_query_next_client(seq, cinfo) >= 0) {
|
||||||
/* reset query info */
|
/* reset query info */
|
||||||
pinfo.client = cinfo.client;
|
snd_seq_port_info_set_client(pinfo, snd_seq_client_info_get_client(cinfo));
|
||||||
pinfo.port = -1;
|
snd_seq_port_info_set_port(pinfo, -1);
|
||||||
count = 0;
|
count = 0;
|
||||||
while (snd_seq_query_next_port(seq, &pinfo) >= 0) {
|
while (snd_seq_query_next_port(seq, pinfo) >= 0) {
|
||||||
if (*group && strcmp(pinfo.group, group))
|
if (check_permission(pinfo, perm)) {
|
||||||
continue;
|
do_action(seq, cinfo, pinfo, count);
|
||||||
if (check_permission(&pinfo, group, perm)) {
|
|
||||||
do_action(seq, &cinfo, &pinfo, count);
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,92 +163,83 @@ static void print_port(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
|
||||||
snd_seq_port_info_t *pinfo, int count)
|
snd_seq_port_info_t *pinfo, int count)
|
||||||
{
|
{
|
||||||
if (! count) {
|
if (! count) {
|
||||||
printf("client %d: '%s' [group=%s] [type=%s]\n",
|
printf("client %d: '%s' [type=%s]\n",
|
||||||
cinfo->client, cinfo->name, cinfo->group,
|
snd_seq_client_info_get_client(cinfo),
|
||||||
(cinfo->type == USER_CLIENT ? "user" : "kernel"));
|
snd_seq_client_info_get_name(cinfo),
|
||||||
|
(snd_seq_client_info_get_type(cinfo) == SND_SEQ_USER_CLIENT ? "user" : "kernel"));
|
||||||
}
|
}
|
||||||
printf(" %3d '%-16s' [group=%s]\n",
|
printf(" %3d '%-16s'\n",
|
||||||
pinfo->port, pinfo->name, pinfo->group);
|
snd_seq_port_info_get_port(pinfo),
|
||||||
|
snd_seq_port_info_get_name(pinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_port_and_subs(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
|
static void print_port_and_subs(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
|
||||||
snd_seq_port_info_t *pinfo, int count)
|
snd_seq_port_info_t *pinfo, int count)
|
||||||
{
|
{
|
||||||
print_port(seq, cinfo, pinfo, count);
|
print_port(seq, cinfo, pinfo, count);
|
||||||
list_subscribers(seq, pinfo->client, pinfo->port);
|
list_subscribers(seq, snd_seq_port_info_get_addr(pinfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* list all ports
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void list_ports(snd_seq_t *seq, char *group, int perm, int list_subs)
|
|
||||||
{
|
|
||||||
if (list_subs)
|
|
||||||
do_search_port(seq, group, perm, print_port_and_subs);
|
|
||||||
else
|
|
||||||
do_search_port(seq, group, perm, print_port);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove all (exported) connections
|
* remove all (exported) connections
|
||||||
*/
|
*/
|
||||||
static void remove_connection(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
|
static void remove_connection(snd_seq_t *seq, snd_seq_client_info_t *cinfo,
|
||||||
snd_seq_port_info_t *pinfo, int count)
|
snd_seq_port_info_t *pinfo, int count)
|
||||||
{
|
{
|
||||||
snd_seq_query_subs_t query;
|
snd_seq_query_subscribe_t *query;
|
||||||
|
|
||||||
memset(&query, 0, sizeof(query));
|
snd_seq_query_subscribe_alloca(&query);
|
||||||
query.client = pinfo->client;
|
snd_seq_query_subscribe_set_root(query, snd_seq_port_info_get_addr(pinfo));
|
||||||
query.port = pinfo->port;
|
|
||||||
|
|
||||||
query.type = SND_SEQ_QUERY_SUBS_READ;
|
snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_READ);
|
||||||
query.index = 0;
|
snd_seq_query_subscribe_set_index(query, 0);
|
||||||
for (query.index = 0; snd_seq_query_port_subscribers(seq, &query) >= 0;
|
for (; snd_seq_query_port_subscribers(seq, query) >= 0;
|
||||||
query.index++) {
|
snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) {
|
||||||
snd_seq_port_info_t port;
|
snd_seq_port_info_t *port;
|
||||||
snd_seq_port_subscribe_t subs;
|
snd_seq_port_subscribe_t *subs;
|
||||||
if (snd_seq_get_any_port_info(seq, query.addr.client, query.addr.port, &port) < 0)
|
const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_root(query);
|
||||||
|
const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_addr(query);
|
||||||
|
snd_seq_port_info_alloca(&port);
|
||||||
|
if (snd_seq_get_any_port_info(seq, dest->client, dest->port, port) < 0)
|
||||||
continue;
|
continue;
|
||||||
if (!(port.capability & SND_SEQ_PORT_CAP_SUBS_READ))
|
if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_READ))
|
||||||
continue;
|
continue;
|
||||||
if (port.capability & SND_SEQ_PORT_CAP_NO_EXPORT)
|
if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT)
|
||||||
continue;
|
continue;
|
||||||
memset(&subs, 0, sizeof(subs));
|
snd_seq_port_subscribe_alloca(&subs);
|
||||||
subs.queue = query.queue;
|
snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query));
|
||||||
subs.sender.client = query.client;
|
snd_seq_port_subscribe_set_sender(subs, sender);
|
||||||
subs.sender.port = query.port;
|
snd_seq_port_subscribe_set_dest(subs, dest);
|
||||||
subs.dest.client = query.addr.client;
|
snd_seq_unsubscribe_port(seq, subs);
|
||||||
subs.dest.port = query.addr.port;
|
|
||||||
snd_seq_unsubscribe_port(seq, &subs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
query.type = SND_SEQ_QUERY_SUBS_WRITE;
|
snd_seq_query_subscribe_set_type(query, SND_SEQ_QUERY_SUBS_WRITE);
|
||||||
query.index = 0;
|
snd_seq_query_subscribe_set_index(query, 0);
|
||||||
for (query.index = 0; snd_seq_query_port_subscribers(seq, &query) >= 0;
|
for (; snd_seq_query_port_subscribers(seq, query) >= 0;
|
||||||
query.index++) {
|
snd_seq_query_subscribe_set_index(query, snd_seq_query_subscribe_get_index(query) + 1)) {
|
||||||
snd_seq_port_info_t port;
|
snd_seq_port_info_t *port;
|
||||||
snd_seq_port_subscribe_t subs;
|
snd_seq_port_subscribe_t *subs;
|
||||||
if (snd_seq_get_any_port_info(seq, query.addr.client, query.addr.port, &port) < 0)
|
const snd_seq_addr_t *dest = snd_seq_query_subscribe_get_root(query);
|
||||||
|
const snd_seq_addr_t *sender = snd_seq_query_subscribe_get_addr(query);
|
||||||
|
snd_seq_port_info_alloca(&port);
|
||||||
|
if (snd_seq_get_any_port_info(seq, sender->client, sender->port, port) < 0)
|
||||||
continue;
|
continue;
|
||||||
if (!(port.capability & SND_SEQ_PORT_CAP_SUBS_WRITE))
|
if (!(snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_SUBS_WRITE))
|
||||||
continue;
|
continue;
|
||||||
if (port.capability & SND_SEQ_PORT_CAP_NO_EXPORT)
|
if (snd_seq_port_info_get_capability(port) & SND_SEQ_PORT_CAP_NO_EXPORT)
|
||||||
continue;
|
continue;
|
||||||
memset(&subs, 0, sizeof(subs));
|
snd_seq_port_subscribe_alloca(&subs);
|
||||||
subs.queue = query.queue;
|
snd_seq_port_subscribe_set_queue(subs, snd_seq_query_subscribe_get_queue(query));
|
||||||
subs.sender.client = query.addr.client;
|
snd_seq_port_subscribe_set_sender(subs, sender);
|
||||||
subs.sender.port = query.addr.port;
|
snd_seq_port_subscribe_set_dest(subs, dest);
|
||||||
subs.dest.client = query.client;
|
snd_seq_unsubscribe_port(seq, subs);
|
||||||
subs.dest.port = query.port;
|
|
||||||
snd_seq_unsubscribe_port(seq, &subs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_all_connections(snd_seq_t *seq)
|
static void remove_all_connections(snd_seq_t *seq)
|
||||||
{
|
{
|
||||||
do_search_port(seq, "", 0, remove_connection);
|
do_search_port(seq, 0, remove_connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,7 +248,7 @@ static void remove_all_connections(snd_seq_t *seq)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SUBSCRIBE, UNSUBSCRIBE, LIST_INPUT, LIST_OUTPUT, REMOVE_ALL
|
SUBSCRIBE, UNSUBSCRIBE, LIST, REMOVE_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct option long_option[] = {
|
static struct option long_option[] = {
|
||||||
|
@ -305,11 +270,11 @@ int main(int argc, char **argv)
|
||||||
snd_seq_t *seq;
|
snd_seq_t *seq;
|
||||||
int queue = 0, convert_time = 0, convert_real = 0, exclusive = 0;
|
int queue = 0, convert_time = 0, convert_real = 0, exclusive = 0;
|
||||||
int command = SUBSCRIBE;
|
int command = SUBSCRIBE;
|
||||||
char *group = "";
|
int list_perm = 0;
|
||||||
int client;
|
int client;
|
||||||
int list_subs = 0;
|
int list_subs = 0;
|
||||||
snd_seq_client_info_t cinfo;
|
snd_seq_port_subscribe_t *subs;
|
||||||
snd_seq_port_subscribe_t subs;
|
snd_seq_addr_t sender, dest;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "diog:r:t:elx", long_option, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "diog:r:t:elx", long_option, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -317,13 +282,12 @@ int main(int argc, char **argv)
|
||||||
command = UNSUBSCRIBE;
|
command = UNSUBSCRIBE;
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
command = LIST_INPUT;
|
command = LIST;
|
||||||
|
list_perm |= LIST_INPUT;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
command = LIST_OUTPUT;
|
command = LIST;
|
||||||
break;
|
list_perm |= LIST_OUTPUT;
|
||||||
case 'g':
|
|
||||||
group = optarg;
|
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
exclusive = 1;
|
exclusive = 1;
|
||||||
|
@ -358,12 +322,9 @@ int main(int argc, char **argv)
|
||||||
snd_lib_error_set_handler(error_handler);
|
snd_lib_error_set_handler(error_handler);
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case LIST_INPUT:
|
case LIST:
|
||||||
list_ports(seq, group, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, list_subs);
|
do_search_port(seq, list_perm,
|
||||||
snd_seq_close(seq);
|
list_subs ? print_port_and_subs : print_port);
|
||||||
return 0;
|
|
||||||
case LIST_OUTPUT:
|
|
||||||
list_ports(seq, group, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, list_subs);
|
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
return 0;
|
return 0;
|
||||||
case REMOVE_ALL:
|
case REMOVE_ALL:
|
||||||
|
@ -387,50 +348,47 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set client info */
|
/* set client info */
|
||||||
memset(&cinfo, 0, sizeof(cinfo));
|
if (snd_seq_set_client_name(seq, "ALSA Connector") < 0) {
|
||||||
cinfo.client = client;
|
|
||||||
cinfo.type = USER_CLIENT;
|
|
||||||
strcpy(cinfo.name, "ALSA Connector");
|
|
||||||
strncpy(cinfo.group, group, sizeof(cinfo.group) - 1);
|
|
||||||
if (snd_seq_set_client_info(seq, &cinfo) < 0) {
|
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
fprintf(stderr, "can't set client info\n");
|
fprintf(stderr, "can't set client info\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set subscription */
|
/* set subscription */
|
||||||
memset(&subs, 0, sizeof(subs));
|
if (snd_seq_parse_address(seq, &sender, argv[optind]) < 0) {
|
||||||
if (parse_address(seq, &subs.sender, argv[optind]) < 0) {
|
|
||||||
fprintf(stderr, "invalid sender address %s\n", argv[optind]);
|
fprintf(stderr, "invalid sender address %s\n", argv[optind]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (parse_address(seq, &subs.dest, argv[optind + 1]) < 0) {
|
if (snd_seq_parse_address(seq, &dest, argv[optind + 1]) < 0) {
|
||||||
fprintf(stderr, "invalid destination address %s\n", argv[optind + 1]);
|
fprintf(stderr, "invalid destination address %s\n", argv[optind + 1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
subs.queue = queue;
|
snd_seq_port_subscribe_alloca(&subs);
|
||||||
subs.exclusive = exclusive;
|
snd_seq_port_subscribe_set_sender(subs, &sender);
|
||||||
subs.convert_time = convert_time;
|
snd_seq_port_subscribe_set_dest(subs, &dest);
|
||||||
subs.realtime = convert_real;
|
snd_seq_port_subscribe_set_queue(subs, queue);
|
||||||
|
snd_seq_port_subscribe_set_exclusive(subs, exclusive);
|
||||||
|
snd_seq_port_subscribe_set_time_update(subs, convert_time);
|
||||||
|
snd_seq_port_subscribe_set_time_real(subs, convert_real);
|
||||||
|
|
||||||
if (command == UNSUBSCRIBE) {
|
if (command == UNSUBSCRIBE) {
|
||||||
if (snd_seq_get_port_subscription(seq, &subs) < 0) {
|
if (snd_seq_get_port_subscription(seq, subs) < 0) {
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
fprintf(stderr, "No subscription is found\n");
|
fprintf(stderr, "No subscription is found\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (snd_seq_unsubscribe_port(seq, &subs) < 0) {
|
if (snd_seq_unsubscribe_port(seq, subs) < 0) {
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
fprintf(stderr, "Disconnection failed (%s)\n", snd_strerror(errno));
|
fprintf(stderr, "Disconnection failed (%s)\n", snd_strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (snd_seq_get_port_subscription(seq, &subs) == 0) {
|
if (snd_seq_get_port_subscription(seq, subs) == 0) {
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
fprintf(stderr, "Connection is already subscribed\n");
|
fprintf(stderr, "Connection is already subscribed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (snd_seq_subscribe_port(seq, &subs) < 0) {
|
if (snd_seq_subscribe_port(seq, subs) < 0) {
|
||||||
snd_seq_close(seq);
|
snd_seq_close(seq);
|
||||||
fprintf(stderr, "Connection failed (%s)\n", snd_strerror(errno));
|
fprintf(stderr, "Connection failed (%s)\n", snd_strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -188,47 +188,6 @@ static void init_pollfds(void)
|
||||||
assert(pollfds);
|
assert(pollfds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* parse command line to client:port
|
|
||||||
* NB: the given string will be broken.
|
|
||||||
*/
|
|
||||||
static int parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, char *arg)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
int client, port;
|
|
||||||
|
|
||||||
if ((p = strpbrk(arg, ":.")) == NULL)
|
|
||||||
return -1;
|
|
||||||
if ((port = atoi(p + 1)) < 0)
|
|
||||||
return -1;
|
|
||||||
addr->port = port;
|
|
||||||
if (isdigit(*arg)) {
|
|
||||||
client = atoi(arg);
|
|
||||||
if (client < 0)
|
|
||||||
return -1;
|
|
||||||
addr->client = client;
|
|
||||||
} else {
|
|
||||||
/* convert from the name */
|
|
||||||
snd_seq_client_info_t cinfo;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
*p = 0;
|
|
||||||
len = strlen(arg);
|
|
||||||
if (len <= 0)
|
|
||||||
return -1;
|
|
||||||
cinfo.client = -1;
|
|
||||||
while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
|
|
||||||
if (! strncmp(cinfo.name, arg, len)) {
|
|
||||||
addr->client = cinfo.client;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1; /* not found */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* close all files
|
* close all files
|
||||||
*/
|
*/
|
||||||
|
@ -301,7 +260,7 @@ static void init_seq(char *source, char *dest)
|
||||||
/* explicit subscriptions */
|
/* explicit subscriptions */
|
||||||
if (source) {
|
if (source) {
|
||||||
/* read subscription */
|
/* read subscription */
|
||||||
if (parse_address(handle, &addr, source) < 0) {
|
if (snd_seq_parse_address(handle, &addr, source) < 0) {
|
||||||
fprintf(stderr, "invalid source address %s\n", source);
|
fprintf(stderr, "invalid source address %s\n", source);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +271,7 @@ static void init_seq(char *source, char *dest)
|
||||||
}
|
}
|
||||||
if (dest) {
|
if (dest) {
|
||||||
/* write subscription */
|
/* write subscription */
|
||||||
if (parse_address(handle, &addr, dest) < 0) {
|
if (snd_seq_parse_address(handle, &addr, dest) < 0) {
|
||||||
fprintf(stderr, "invalid destination address %s\n", dest);
|
fprintf(stderr, "invalid destination address %s\n", dest);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue