--- a/scctl_src/scctl.cpp
+++ b/scctl_src/scctl.cpp
@@ -344,11 +344,15 @@
static char *thisprog;
static char usage [] =
-" -l list renderers with Songcast Receiver capability\n"
+" -l List renderers with Songcast Receiver capability\n"
" -s <master> <slave> [slave ...] : Set up the slaves renderers as Songcast\n"
" Receivers and make them play from the same uri as the master\n"
" -x <renderer> [renderer ...] Reset renderers from Songcast to Playlist\n"
-" -S run as server\n"
+" -S Run as server\n"
+" -f If no server is found, scctl will fork one after performing the\n"
+" requested command, so that the next execution will not have to wait for\n"
+" the discovery timeout.n"
+" -h This help.\n"
"\n"
"Renderers may be designated by friendly name or UUID\n"
"\n"
@@ -359,37 +363,46 @@
fprintf(fp, "%s: usage:\n%s", thisprog, usage);
exit(1);
}
+
static int op_flags;
#define OPT_l 0x1
#define OPT_s 0x2
#define OPT_x 0x4
#define OPT_S 0x8
#define OPT_h 0x10
+#define OPT_f 0x20
+#define OPT_p 0x40
int runserver();
-bool tryserver(int argc, char *argv[]);
+bool tryserver(int flags, int argc, char *argv[]);
int main(int argc, char *argv[])
{
thisprog = argv[0];
int ret;
- while ((ret = getopt(argc, argv, "lSsxh")) != -1) {
+ while ((ret = getopt(argc, argv, "fhlsSx")) != -1) {
switch (ret) {
- case 'l': if (op_flags) Usage(); op_flags |= OPT_l; break;
- case 's': if (op_flags) Usage(); op_flags |= OPT_s; break;
- case 'S': if (op_flags) Usage(); op_flags |= OPT_S; break;
- case 'x': if (op_flags) Usage(); op_flags |= OPT_x; break;
- case 'h': Usage(stdout);
+ case 'f': op_flags |= OPT_f; break;
+ case 'h': Usage(stdout); break;
+ case 'l': op_flags |= OPT_l; break;
+ case 's': op_flags |= OPT_s; break;
+ case 'S': op_flags |= OPT_S; break;
+ case 'x': op_flags |= OPT_x; break;
default: Usage();
}
}
+ //fprintf(stderr, "argc %d optind %d flgs: 0x%x\n", argc, optind, op_flags);
// If we're not a server, try to contact one to avoid the
// discovery timeout
- if (!(op_flags & OPT_S) && tryserver(argc -1, &argv[1])) {
+ if (!(op_flags & OPT_S) && tryserver(op_flags, argc -optind,
+ &argv[optind])) {
exit(0);
}
+
+ if ((op_flags & ~OPT_f) == 0)
+ Usage();
LibUPnP *mylib = LibUPnP::getLibUPnP();
if (!mylib) {
@@ -435,12 +448,20 @@
slaves.push_back(argv[optind++]);
}
ohNoSongcast(slaves);
- } else if (op_flags & OPT_S) {
+ } else if ((op_flags & OPT_S)) {
exit(runserver());
} else {
Usage();
}
+ // If we get here, we have executed a local command. If -f is set,
+ // fork and run the server code so that a next execution will use
+ // this instead (and not incur the discovery timeout)
+ if ((op_flags & OPT_f)) {
+ // Father exits, son process becomes server
+ if (daemon(0, 0) == 0)
+ runserver();
+ }
return 0;
}
@@ -505,9 +526,13 @@
return true;
}
-bool tryserver(int argc, char **argv)
-{
- string cmd;
+bool tryserver(int opflags, int argc, char **argv)
+{
+ char opts[30];
+ sprintf(opts, "0x%x", opflags);
+ string cmd(opts);
+ cmd += " ";
+
for (int i = 0; i < argc; i++) {
// May need quoting here ?
cmd += argv[i];
@@ -549,21 +574,25 @@
}
trimstring(line, " \n");
+
+ LOGDEB1("scctl: server: got cmd: " << line << endl);
+
vector<string> toks;
stringToTokens(line, toks);
if (toks.empty()) {
return 1;
}
- string cmd = toks[0];
+ int opflags = strtoul(toks[0].c_str(), 0, 0);
+
string out;
- if (!cmd.compare("-p")) {
+ if (opflags & OPT_p) {
// ping
out = "Ok\n";
- } else if (!cmd.compare("-l")) {
+ } else if (opflags & OPT_l) {
out = showReceivers();
- } else if (!cmd.compare("-s")) {
- if (cmd.size() < 3)
+ } else if (opflags & OPT_s) {
+ if (toks.size() < 3)
return 1;
vector<string>::iterator beg = toks.begin();
beg++;
@@ -571,14 +600,15 @@
beg++;
vector<string> slaves(beg, toks.end());
ohSongcast(master, slaves);
- } else if (!cmd.compare("-x")) {
- if (cmd.size() < 2)
+ } else if (opflags & OPT_x) {
+ if (toks.size() < 2)
return 1;
vector<string>::iterator beg = toks.begin();
beg++;
vector<string> slaves(beg, toks.end());
ohNoSongcast(slaves);
} else {
+ LOGERR("scctl: server: bad cmd:" << toks[0] << endl);
return 1;
}