|
a/scctl_src/scctl.cpp |
|
b/scctl_src/scctl.cpp |
|
... |
|
... |
342 |
return out.str();
|
342 |
return out.str();
|
343 |
}
|
343 |
}
|
344 |
|
344 |
|
345 |
static char *thisprog;
|
345 |
static char *thisprog;
|
346 |
static char usage [] =
|
346 |
static char usage [] =
|
347 |
" -l list renderers with Songcast Receiver capability\n"
|
347 |
" -l List renderers with Songcast Receiver capability\n"
|
348 |
" -s <master> <slave> [slave ...] : Set up the slaves renderers as Songcast\n"
|
348 |
" -s <master> <slave> [slave ...] : Set up the slaves renderers as Songcast\n"
|
349 |
" Receivers and make them play from the same uri as the master\n"
|
349 |
" Receivers and make them play from the same uri as the master\n"
|
350 |
" -x <renderer> [renderer ...] Reset renderers from Songcast to Playlist\n"
|
350 |
" -x <renderer> [renderer ...] Reset renderers from Songcast to Playlist\n"
|
351 |
" -S run as server\n"
|
351 |
" -S Run as server\n"
|
|
|
352 |
" -f If no server is found, scctl will fork one after performing the\n"
|
|
|
353 |
" requested command, so that the next execution will not have to wait for\n"
|
|
|
354 |
" the discovery timeout.n"
|
|
|
355 |
" -h This help.\n"
|
352 |
"\n"
|
356 |
"\n"
|
353 |
"Renderers may be designated by friendly name or UUID\n"
|
357 |
"Renderers may be designated by friendly name or UUID\n"
|
354 |
"\n"
|
358 |
"\n"
|
355 |
;
|
359 |
;
|
356 |
static void
|
360 |
static void
|
357 |
Usage(FILE *fp = stderr)
|
361 |
Usage(FILE *fp = stderr)
|
358 |
{
|
362 |
{
|
359 |
fprintf(fp, "%s: usage:\n%s", thisprog, usage);
|
363 |
fprintf(fp, "%s: usage:\n%s", thisprog, usage);
|
360 |
exit(1);
|
364 |
exit(1);
|
361 |
}
|
365 |
}
|
|
|
366 |
|
362 |
static int op_flags;
|
367 |
static int op_flags;
|
363 |
#define OPT_l 0x1
|
368 |
#define OPT_l 0x1
|
364 |
#define OPT_s 0x2
|
369 |
#define OPT_s 0x2
|
365 |
#define OPT_x 0x4
|
370 |
#define OPT_x 0x4
|
366 |
#define OPT_S 0x8
|
371 |
#define OPT_S 0x8
|
367 |
#define OPT_h 0x10
|
372 |
#define OPT_h 0x10
|
|
|
373 |
#define OPT_f 0x20
|
|
|
374 |
#define OPT_p 0x40
|
368 |
|
375 |
|
369 |
int runserver();
|
376 |
int runserver();
|
370 |
bool tryserver(int argc, char *argv[]);
|
377 |
bool tryserver(int flags, int argc, char *argv[]);
|
371 |
|
378 |
|
372 |
int main(int argc, char *argv[])
|
379 |
int main(int argc, char *argv[])
|
373 |
{
|
380 |
{
|
374 |
thisprog = argv[0];
|
381 |
thisprog = argv[0];
|
375 |
|
382 |
|
376 |
int ret;
|
383 |
int ret;
|
377 |
while ((ret = getopt(argc, argv, "lSsxh")) != -1) {
|
384 |
while ((ret = getopt(argc, argv, "fhlsSx")) != -1) {
|
378 |
switch (ret) {
|
385 |
switch (ret) {
|
379 |
case 'l': if (op_flags) Usage(); op_flags |= OPT_l; break;
|
386 |
case 'f': op_flags |= OPT_f; break;
|
380 |
case 's': if (op_flags) Usage(); op_flags |= OPT_s; break;
|
|
|
381 |
case 'S': if (op_flags) Usage(); op_flags |= OPT_S; break;
|
|
|
382 |
case 'x': if (op_flags) Usage(); op_flags |= OPT_x; break;
|
|
|
383 |
case 'h': Usage(stdout);
|
387 |
case 'h': Usage(stdout); break;
|
|
|
388 |
case 'l': op_flags |= OPT_l; break;
|
|
|
389 |
case 's': op_flags |= OPT_s; break;
|
|
|
390 |
case 'S': op_flags |= OPT_S; break;
|
|
|
391 |
case 'x': op_flags |= OPT_x; break;
|
384 |
default: Usage();
|
392 |
default: Usage();
|
385 |
}
|
393 |
}
|
386 |
}
|
394 |
}
|
|
|
395 |
//fprintf(stderr, "argc %d optind %d flgs: 0x%x\n", argc, optind, op_flags);
|
387 |
|
396 |
|
388 |
// If we're not a server, try to contact one to avoid the
|
397 |
// If we're not a server, try to contact one to avoid the
|
389 |
// discovery timeout
|
398 |
// discovery timeout
|
390 |
if (!(op_flags & OPT_S) && tryserver(argc -1, &argv[1])) {
|
399 |
if (!(op_flags & OPT_S) && tryserver(op_flags, argc -optind,
|
|
|
400 |
&argv[optind])) {
|
391 |
exit(0);
|
401 |
exit(0);
|
392 |
}
|
402 |
}
|
|
|
403 |
|
|
|
404 |
if ((op_flags & ~OPT_f) == 0)
|
|
|
405 |
Usage();
|
393 |
|
406 |
|
394 |
LibUPnP *mylib = LibUPnP::getLibUPnP();
|
407 |
LibUPnP *mylib = LibUPnP::getLibUPnP();
|
395 |
if (!mylib) {
|
408 |
if (!mylib) {
|
396 |
cerr << "Can't get LibUPnP" << endl;
|
409 |
cerr << "Can't get LibUPnP" << endl;
|
397 |
return 1;
|
410 |
return 1;
|
|
... |
|
... |
433 |
vector<string> slaves;
|
446 |
vector<string> slaves;
|
434 |
while (optind < argc) {
|
447 |
while (optind < argc) {
|
435 |
slaves.push_back(argv[optind++]);
|
448 |
slaves.push_back(argv[optind++]);
|
436 |
}
|
449 |
}
|
437 |
ohNoSongcast(slaves);
|
450 |
ohNoSongcast(slaves);
|
438 |
} else if (op_flags & OPT_S) {
|
451 |
} else if ((op_flags & OPT_S)) {
|
439 |
exit(runserver());
|
452 |
exit(runserver());
|
440 |
} else {
|
453 |
} else {
|
441 |
Usage();
|
454 |
Usage();
|
442 |
}
|
455 |
}
|
443 |
|
456 |
|
|
|
457 |
// If we get here, we have executed a local command. If -f is set,
|
|
|
458 |
// fork and run the server code so that a next execution will use
|
|
|
459 |
// this instead (and not incur the discovery timeout)
|
|
|
460 |
if ((op_flags & OPT_f)) {
|
|
|
461 |
// Father exits, son process becomes server
|
|
|
462 |
if (daemon(0, 0) == 0)
|
|
|
463 |
runserver();
|
|
|
464 |
}
|
444 |
return 0;
|
465 |
return 0;
|
445 |
}
|
466 |
}
|
446 |
|
467 |
|
447 |
// The Unix socket path which we use for client-server operation
|
468 |
// The Unix socket path which we use for client-server operation
|
448 |
bool sockname(string& nm)
|
469 |
bool sockname(string& nm)
|
|
... |
|
... |
503 |
}
|
524 |
}
|
504 |
}
|
525 |
}
|
505 |
return true;
|
526 |
return true;
|
506 |
}
|
527 |
}
|
507 |
|
528 |
|
508 |
bool tryserver(int argc, char **argv)
|
529 |
bool tryserver(int opflags, int argc, char **argv)
|
509 |
{
|
530 |
{
|
|
|
531 |
char opts[30];
|
|
|
532 |
sprintf(opts, "0x%x", opflags);
|
510 |
string cmd;
|
533 |
string cmd(opts);
|
|
|
534 |
cmd += " ";
|
|
|
535 |
|
511 |
for (int i = 0; i < argc; i++) {
|
536 |
for (int i = 0; i < argc; i++) {
|
512 |
// May need quoting here ?
|
537 |
// May need quoting here ?
|
513 |
cmd += argv[i];
|
538 |
cmd += argv[i];
|
514 |
cmd += " ";
|
539 |
cmd += " ";
|
515 |
}
|
540 |
}
|
|
... |
|
... |
547 |
}
|
572 |
}
|
548 |
line = buf;
|
573 |
line = buf;
|
549 |
}
|
574 |
}
|
550 |
|
575 |
|
551 |
trimstring(line, " \n");
|
576 |
trimstring(line, " \n");
|
|
|
577 |
|
|
|
578 |
LOGDEB1("scctl: server: got cmd: " << line << endl);
|
|
|
579 |
|
552 |
vector<string> toks;
|
580 |
vector<string> toks;
|
553 |
stringToTokens(line, toks);
|
581 |
stringToTokens(line, toks);
|
554 |
if (toks.empty()) {
|
582 |
if (toks.empty()) {
|
555 |
return 1;
|
583 |
return 1;
|
556 |
}
|
584 |
}
|
557 |
|
585 |
|
558 |
string cmd = toks[0];
|
586 |
int opflags = strtoul(toks[0].c_str(), 0, 0);
|
|
|
587 |
|
559 |
string out;
|
588 |
string out;
|
560 |
if (!cmd.compare("-p")) {
|
589 |
if (opflags & OPT_p) {
|
561 |
// ping
|
590 |
// ping
|
562 |
out = "Ok\n";
|
591 |
out = "Ok\n";
|
563 |
} else if (!cmd.compare("-l")) {
|
592 |
} else if (opflags & OPT_l) {
|
564 |
out = showReceivers();
|
593 |
out = showReceivers();
|
565 |
} else if (!cmd.compare("-s")) {
|
594 |
} else if (opflags & OPT_s) {
|
566 |
if (cmd.size() < 3)
|
595 |
if (toks.size() < 3)
|
567 |
return 1;
|
596 |
return 1;
|
568 |
vector<string>::iterator beg = toks.begin();
|
597 |
vector<string>::iterator beg = toks.begin();
|
569 |
beg++;
|
598 |
beg++;
|
570 |
string master = *beg;
|
599 |
string master = *beg;
|
571 |
beg++;
|
600 |
beg++;
|
572 |
vector<string> slaves(beg, toks.end());
|
601 |
vector<string> slaves(beg, toks.end());
|
573 |
ohSongcast(master, slaves);
|
602 |
ohSongcast(master, slaves);
|
574 |
} else if (!cmd.compare("-x")) {
|
603 |
} else if (opflags & OPT_x) {
|
575 |
if (cmd.size() < 2)
|
604 |
if (toks.size() < 2)
|
576 |
return 1;
|
605 |
return 1;
|
577 |
vector<string>::iterator beg = toks.begin();
|
606 |
vector<string>::iterator beg = toks.begin();
|
578 |
beg++;
|
607 |
beg++;
|
579 |
vector<string> slaves(beg, toks.end());
|
608 |
vector<string> slaves(beg, toks.end());
|
580 |
ohNoSongcast(slaves);
|
609 |
ohNoSongcast(slaves);
|
581 |
} else {
|
610 |
} else {
|
|
|
611 |
LOGERR("scctl: server: bad cmd:" << toks[0] << endl);
|
582 |
return 1;
|
612 |
return 1;
|
583 |
}
|
613 |
}
|
584 |
|
614 |
|
585 |
if (con->send(out.c_str(), out.size(), 0) < 0) {
|
615 |
if (con->send(out.c_str(), out.size(), 0) < 0) {
|
586 |
LOGERR("scctl: server: send() failed\n");
|
616 |
LOGERR("scctl: server: send() failed\n");
|