Conflicts: common/JackEngine.cpp common/JackServer.cpptags/v1.9.10
@@ -82,4 +82,6 @@ | |||||
#define EMPTY 0xFFFD | #define EMPTY 0xFFFD | ||||
#define FREE 0xFFFC | #define FREE 0xFFFC | ||||
#define JACK_DEFAULT_SELF_CONNECT_MODE JackSelfConnectIgnoreAll | |||||
#endif | #endif |
@@ -47,6 +47,13 @@ | |||||
using namespace Jack; | using namespace Jack; | ||||
#define SELF_CONNECT_MODE_ALLOW_CHAR ' ' | |||||
#define SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR 'E' | |||||
#define SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR 'e' | |||||
#define SELF_CONNECT_MODE_FAIL_ALL_CHAR 'A' | |||||
#define SELF_CONNECT_MODE_IGNORE_ALL_CHAR 'a' | |||||
#define SELF_CONNECT_MODES_COUNT 5 | |||||
struct jackctl_server | struct jackctl_server | ||||
{ | { | ||||
JSList * drivers; | JSList * drivers; | ||||
@@ -94,6 +101,12 @@ struct jackctl_server | |||||
/* bool, synchronous or asynchronous engine mode */ | /* bool, synchronous or asynchronous engine mode */ | ||||
union jackctl_parameter_value sync; | union jackctl_parameter_value sync; | ||||
union jackctl_parameter_value default_sync; | union jackctl_parameter_value default_sync; | ||||
/* char enum, self connect mode mode */ | |||||
union jackctl_parameter_value self_connect_mode; | |||||
union jackctl_parameter_value default_self_connect_mode; | |||||
jack_driver_param_value_enum_t self_connect_mode_possible_values[SELF_CONNECT_MODES_COUNT]; | |||||
jack_driver_param_constraint_desc_t self_connect_mode_constraint; | |||||
}; | }; | ||||
struct jackctl_driver | struct jackctl_driver | ||||
@@ -869,6 +882,40 @@ SERVER_EXPORT jackctl_server_t * jackctl_server_create( | |||||
goto fail_free_parameters; | goto fail_free_parameters; | ||||
} | } | ||||
server_ptr->self_connect_mode_constraint.flags = JACK_CONSTRAINT_FLAG_STRICT | JACK_CONSTRAINT_FLAG_FAKE_VALUE; | |||||
server_ptr->self_connect_mode_constraint.constraint.enumeration.count = SELF_CONNECT_MODES_COUNT; | |||||
server_ptr->self_connect_mode_constraint.constraint.enumeration.possible_values_array = server_ptr->self_connect_mode_possible_values; | |||||
server_ptr->self_connect_mode_possible_values[0].value.c = SELF_CONNECT_MODE_ALLOW_CHAR; | |||||
strcpy(server_ptr->self_connect_mode_possible_values[0].short_desc, "Don't restrict self connect requests"); | |||||
server_ptr->self_connect_mode_possible_values[1].value.c = SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR ; | |||||
strcpy(server_ptr->self_connect_mode_possible_values[1].short_desc, "Fail self connect requests to external ports only"); | |||||
server_ptr->self_connect_mode_possible_values[2].value.c = SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR; | |||||
strcpy(server_ptr->self_connect_mode_possible_values[2].short_desc, "Ignore self connect requests to external ports only"); | |||||
server_ptr->self_connect_mode_possible_values[3].value.c = SELF_CONNECT_MODE_FAIL_ALL_CHAR; | |||||
strcpy(server_ptr->self_connect_mode_possible_values[3].short_desc, "Fail all self connect requests"); | |||||
server_ptr->self_connect_mode_possible_values[4].value.c = SELF_CONNECT_MODE_IGNORE_ALL_CHAR; | |||||
strcpy(server_ptr->self_connect_mode_possible_values[4].short_desc, "Ignore all self connect requests"); | |||||
value.c = SELF_CONNECT_MODE_ALLOW_CHAR; | |||||
if (jackctl_add_parameter( | |||||
&server_ptr->parameters, | |||||
"self-connect-mode", | |||||
"Self connect mode.", | |||||
"Whether JACK clients are allowed to connect their own ports", | |||||
JackParamChar, | |||||
&server_ptr->self_connect_mode, | |||||
&server_ptr->default_self_connect_mode, | |||||
value, | |||||
&server_ptr->self_connect_mode_constraint) == NULL) | |||||
{ | |||||
goto fail_free_parameters; | |||||
} | |||||
JackServerGlobals::on_device_acquire = on_device_acquire; | JackServerGlobals::on_device_acquire = on_device_acquire; | ||||
JackServerGlobals::on_device_release = on_device_release; | JackServerGlobals::on_device_release = on_device_release; | ||||
@@ -953,6 +1000,7 @@ jackctl_server_open( | |||||
jackctl_server *server_ptr, | jackctl_server *server_ptr, | ||||
jackctl_driver *driver_ptr) | jackctl_driver *driver_ptr) | ||||
{ | { | ||||
JackSelfConnectMode self_connect_mode; | |||||
JSList * paramlist = NULL; | JSList * paramlist = NULL; | ||||
try { | try { | ||||
@@ -986,6 +1034,27 @@ jackctl_server_open( | |||||
server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ | server_ptr->client_timeout.i = 500; /* 0.5 sec; usable when non realtime. */ | ||||
} | } | ||||
switch (server_ptr->self_connect_mode.c) | |||||
{ | |||||
case SELF_CONNECT_MODE_ALLOW_CHAR: | |||||
self_connect_mode = JackSelfConnectAllow; | |||||
break; | |||||
case SELF_CONNECT_MODE_FAIL_EXTERNAL_ONLY_CHAR: | |||||
self_connect_mode = JackSelfConnectFailExternalOnly; | |||||
break; | |||||
case SELF_CONNECT_MODE_IGNORE_EXTERNAL_ONLY_CHAR: | |||||
self_connect_mode = JackSelfConnectIgnoreExternalOnly; | |||||
break; | |||||
case SELF_CONNECT_MODE_FAIL_ALL_CHAR: | |||||
self_connect_mode = JackSelfConnectFailAll; | |||||
break; | |||||
case SELF_CONNECT_MODE_IGNORE_ALL_CHAR: | |||||
self_connect_mode = JackSelfConnectIgnoreAll; | |||||
break; | |||||
default: | |||||
self_connect_mode = JACK_DEFAULT_SELF_CONNECT_MODE; | |||||
} | |||||
/* check port max value before allocating server */ | /* check port max value before allocating server */ | ||||
if (server_ptr->port_max.ui > PORT_NUM_MAX) { | if (server_ptr->port_max.ui > PORT_NUM_MAX) { | ||||
jack_error("Jack server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); | jack_error("Jack server started with too much ports %d (when port max can be %d)", server_ptr->port_max.ui, PORT_NUM_MAX); | ||||
@@ -1002,6 +1071,7 @@ jackctl_server_open( | |||||
server_ptr->port_max.ui, | server_ptr->port_max.ui, | ||||
server_ptr->verbose.b, | server_ptr->verbose.b, | ||||
(jack_timer_type_t)server_ptr->clock_source.ui, | (jack_timer_type_t)server_ptr->clock_source.ui, | ||||
self_connect_mode, | |||||
server_ptr->name.str); | server_ptr->name.str); | ||||
if (server_ptr->engine == NULL) | if (server_ptr->engine == NULL) | ||||
{ | { | ||||
@@ -38,13 +38,15 @@ namespace Jack | |||||
JackEngine::JackEngine(JackGraphManager* manager, | JackEngine::JackEngine(JackGraphManager* manager, | ||||
JackSynchro* table, | JackSynchro* table, | ||||
JackEngineControl* control) | |||||
JackEngineControl* control, | |||||
JackSelfConnectMode self_connect_mode) | |||||
: JackLockAble(control->fServerName), | : JackLockAble(control->fServerName), | ||||
fSignal(control->fServerName) | fSignal(control->fServerName) | ||||
{ | { | ||||
fGraphManager = manager; | fGraphManager = manager; | ||||
fSynchroTable = table; | fSynchroTable = table; | ||||
fEngineControl = control; | fEngineControl = control; | ||||
fSelfConnectMode = self_connect_mode; | |||||
for (int i = 0; i < CLIENT_NUM; i++) { | for (int i = 0; i < CLIENT_NUM; i++) { | ||||
fClientTable[i] = NULL; | fClientTable[i] = NULL; | ||||
} | } | ||||
@@ -803,10 +805,10 @@ int JackEngine::ClientDeactivate(int refnum) | |||||
// First disconnect all ports | // First disconnect all ports | ||||
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | ||||
PortDisconnect(refnum, input_ports[i], ALL_PORTS); | |||||
PortDisconnect(-1, input_ports[i], ALL_PORTS); | |||||
} | } | ||||
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { | for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { | ||||
PortDisconnect(refnum, output_ports[i], ALL_PORTS); | |||||
PortDisconnect(-1, output_ports[i], ALL_PORTS); | |||||
} | } | ||||
// Then issue port registration notification | // Then issue port registration notification | ||||
@@ -874,7 +876,7 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) | |||||
assert(client); | assert(client); | ||||
// Disconnect port ==> notification is sent | // Disconnect port ==> notification is sent | ||||
PortDisconnect(refnum, port_index, ALL_PORTS); | |||||
PortDisconnect(-1, port_index, ALL_PORTS); | |||||
if (fGraphManager->ReleasePort(refnum, port_index) == 0) { | if (fGraphManager->ReleasePort(refnum, port_index) == 0) { | ||||
if (client->GetClientControl()->fActive) { | if (client->GetClientControl()->fActive) { | ||||
@@ -886,6 +888,72 @@ int JackEngine::PortUnRegister(int refnum, jack_port_id_t port_index) | |||||
} | } | ||||
} | } | ||||
// this check is to prevent apps to self connect to other apps | |||||
// TODO: make this work with multiple clients per app | |||||
int JackEngine::CheckPortsConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) | |||||
{ | |||||
JackPort* src_port = fGraphManager->GetPort(src); | |||||
JackPort* dst_port = fGraphManager->GetPort(dst); | |||||
jack_log("CheckPortsConnect(caller = %d, src = %d, dst = %d)", refnum, src_port->GetRefNum(), dst_port->GetRefNum()); | |||||
int src_self = src_port->GetRefNum() == refnum ? 1 : 0; | |||||
int dst_self = dst_port->GetRefNum() == refnum ? 1 : 0; | |||||
jack_log("src_self is %s", src_self ? "true" : "false"); | |||||
jack_log("dst_self is %s", dst_self ? "true" : "false"); | |||||
// 0 means client is connecting other client ports (i.e. control app patchbay functionality) | |||||
// 1 means client is connecting its own port to port of other client (i.e. self hooking into system app) | |||||
// 2 means client is connecting its own ports (i.e. for app internal functionality) | |||||
// TODO: Make this check an engine option and more tweakable (return error or success) | |||||
// MAYBE: make the engine option changable on the fly and expose it through client or control API | |||||
switch (fSelfConnectMode) | |||||
{ | |||||
case JackSelfConnectFailExternalOnly: | |||||
if (src_self + dst_self == 1) | |||||
{ | |||||
jack_info("rejecting port self connect request to external port (%s -> %s)", src_port->GetName(), dst_port->GetName()); | |||||
return -1; | |||||
} | |||||
return 1; | |||||
case JackSelfConnectIgnoreExternalOnly: | |||||
if (src_self + dst_self == 1) | |||||
{ | |||||
jack_info("ignoring port self connect request to external port (%s -> %s)", src_port->GetName(), dst_port->GetName()); | |||||
return 0; | |||||
} | |||||
return 1; | |||||
case JackSelfConnectFailAll: | |||||
if (src_self + dst_self != 0) | |||||
{ | |||||
jack_info("rejecting port self connect request (%s -> %s)", src_port->GetName(), dst_port->GetName()); | |||||
return -1; | |||||
} | |||||
return 1; | |||||
case JackSelfConnectIgnoreAll: | |||||
if (src_self + dst_self != 0) | |||||
{ | |||||
jack_info("ignoring port self connect request (%s -> %s)", src_port->GetName(), dst_port->GetName()); | |||||
return 0; | |||||
} | |||||
return 1; | |||||
case JackSelfConnectAllow: // fix warning | |||||
return 1; | |||||
} | |||||
return 1; | |||||
} | |||||
int JackEngine::PortConnect(int refnum, const char* src, const char* dst) | int JackEngine::PortConnect(int refnum, const char* src, const char* dst) | ||||
{ | { | ||||
jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst); | jack_log("JackEngine::PortConnect src = %s dst = %s", src, dst); | ||||
@@ -926,7 +994,12 @@ int JackEngine::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) | |||||
return -1; | return -1; | ||||
} | } | ||||
int res = fGraphManager->Connect(src, dst); | |||||
int res = CheckPortsConnect(refnum, src, dst); | |||||
if (res != 1) { | |||||
return res; | |||||
} | |||||
res = fGraphManager->Connect(src, dst); | |||||
if (res == 0) { | if (res == 0) { | ||||
NotifyPortConnect(src, dst, true); | NotifyPortConnect(src, dst, true); | ||||
} | } | ||||
@@ -969,15 +1042,21 @@ int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t ds | |||||
} | } | ||||
return res; | return res; | ||||
} else if (fGraphManager->CheckPorts(src, dst) < 0) { | |||||
return -1; | |||||
} else if (fGraphManager->Disconnect(src, dst) == 0) { | |||||
// Notifications | |||||
NotifyPortConnect(src, dst, false); | |||||
return 0; | |||||
} else { | |||||
} | |||||
if (fGraphManager->CheckPorts(src, dst) < 0) { | |||||
return -1; | return -1; | ||||
} | } | ||||
int res = CheckPortsConnect(refnum, src, dst); | |||||
if (res != 1) { | |||||
return res; | |||||
} | |||||
res = fGraphManager->Disconnect(src, dst); | |||||
if (res == 0) | |||||
NotifyPortConnect(src, dst, false); | |||||
return res; | |||||
} | } | ||||
int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) | int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) | ||||
@@ -49,6 +49,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||||
JackGraphManager* fGraphManager; | JackGraphManager* fGraphManager; | ||||
JackEngineControl* fEngineControl; | JackEngineControl* fEngineControl; | ||||
JackSelfConnectMode fSelfConnectMode; | |||||
JackClientInterface* fClientTable[CLIENT_NUM]; | JackClientInterface* fClientTable[CLIENT_NUM]; | ||||
JackSynchro* fSynchroTable; | JackSynchro* fSynchroTable; | ||||
JackServerNotifyChannel fChannel; /*! To communicate between the RT thread and server */ | JackServerNotifyChannel fChannel; /*! To communicate between the RT thread and server */ | ||||
@@ -94,9 +95,11 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||||
return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); | return (refnum >= 0 && refnum < CLIENT_NUM && fClientTable[refnum] != NULL); | ||||
} | } | ||||
int CheckPortsConnect(int refnum, jack_port_id_t src, jack_port_id_t dst); | |||||
public: | public: | ||||
JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler); | |||||
JackEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, JackSelfConnectMode self_connect_mode); | |||||
~JackEngine(); | ~JackEngine(); | ||||
int Open(); | int Open(); | ||||
@@ -83,8 +83,8 @@ class SERVER_EXPORT JackLockedEngine | |||||
public: | public: | ||||
JackLockedEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler): | |||||
fEngine(manager, table, controler) | |||||
JackLockedEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, JackSelfConnectMode self_connect_mode): | |||||
fEngine(manager, table, controler, self_connect_mode) | |||||
{} | {} | ||||
~JackLockedEngine() | ~JackLockedEngine() | ||||
{} | {} | ||||
@@ -40,8 +40,7 @@ namespace Jack | |||||
//---------------- | //---------------- | ||||
// Server control | // Server control | ||||
//---------------- | //---------------- | ||||
JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name) | |||||
JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, JackSelfConnectMode self_connect_mode, const char* server_name) | |||||
{ | { | ||||
if (rt) { | if (rt) { | ||||
jack_info("JACK server starting in realtime mode with priority %ld", priority); | jack_info("JACK server starting in realtime mode with priority %ld", priority); | ||||
@@ -51,7 +50,7 @@ JackServer::JackServer(bool sync, bool temporary, int timeout, bool rt, int prio | |||||
fGraphManager = JackGraphManager::Allocate(port_max); | fGraphManager = JackGraphManager::Allocate(port_max); | ||||
fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); | fEngineControl = new JackEngineControl(sync, temporary, timeout, rt, priority, verbose, clock, server_name); | ||||
fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl); | |||||
fEngine = new JackLockedEngine(fGraphManager, GetSynchroTable(), fEngineControl, self_connect_mode); | |||||
// A distinction is made between the threaded freewheel driver and the | // A distinction is made between the threaded freewheel driver and the | ||||
// regular freewheel driver because the freewheel driver needs to run in | // regular freewheel driver because the freewheel driver needs to run in | ||||
@@ -64,7 +64,7 @@ class SERVER_EXPORT JackServer | |||||
public: | public: | ||||
JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, const char* server_name); | |||||
JackServer(bool sync, bool temporary, int timeout, bool rt, int priority, int port_max, bool verbose, jack_timer_type_t clock, JackSelfConnectMode self_connect_mode, const char* server_name); | |||||
~JackServer(); | ~JackServer(); | ||||
// Server control | // Server control | ||||
@@ -47,10 +47,11 @@ int JackServerGlobals::Start(const char* server_name, | |||||
int priority, | int priority, | ||||
int port_max, | int port_max, | ||||
int verbose, | int verbose, | ||||
jack_timer_type_t clock) | |||||
jack_timer_type_t clock, | |||||
JackSelfConnectMode self_connect_mode) | |||||
{ | { | ||||
jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); | jack_log("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld ", sync, time_out_ms, rt, priority, verbose); | ||||
new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, server_name); // Will setup fInstance and fUserCount globals | |||||
new JackServer(sync, temporary, time_out_ms, rt, priority, port_max, verbose, clock, self_connect_mode, server_name); // Will setup fInstance and fUserCount globals | |||||
int res = fInstance->Open(driver_desc, driver_params); | int res = fInstance->Open(driver_desc, driver_params); | ||||
return (res < 0) ? res : fInstance->Start(); | return (res < 0) ? res : fInstance->Start(); | ||||
} | } | ||||
@@ -336,7 +337,7 @@ bool JackServerGlobals::Init() | |||||
free(argv[i]); | free(argv[i]); | ||||
} | } | ||||
int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source); | |||||
int res = Start(server_name, driver_desc, master_driver_params, sync, temporary, client_timeout, realtime, realtime_priority, port_max, verbose_aux, clock_source, JACK_DEFAULT_SELF_CONNECT_MODE); | |||||
if (res < 0) { | if (res < 0) { | ||||
jack_error("Cannot start server... exit"); | jack_error("Cannot start server... exit"); | ||||
Delete(); | Delete(); | ||||
@@ -60,7 +60,8 @@ struct SERVER_EXPORT JackServerGlobals | |||||
int priority, | int priority, | ||||
int port_max, | int port_max, | ||||
int verbose, | int verbose, | ||||
jack_timer_type_t clock); | |||||
jack_timer_type_t clock, | |||||
JackSelfConnectMode self_connect_mode); | |||||
static void Stop(); | static void Stop(); | ||||
static void Delete(); | static void Delete(); | ||||
}; | }; | ||||
@@ -50,4 +50,14 @@ typedef enum { | |||||
Finished, | Finished, | ||||
} jack_client_state_t; | } jack_client_state_t; | ||||
enum JackSelfConnectMode | |||||
{ | |||||
JackSelfConnectAllow, | |||||
JackSelfConnectFailExternalOnly, | |||||
JackSelfConnectIgnoreExternalOnly, | |||||
JackSelfConnectFailAll, | |||||
JackSelfConnectIgnoreAll, | |||||
}; | |||||
#endif | #endif |
@@ -203,8 +203,8 @@ int main(int argc, char** argv) | |||||
jackctl_driver_t * master_driver_ctl; | jackctl_driver_t * master_driver_ctl; | ||||
jackctl_driver_t * loopback_driver_ctl = NULL; | jackctl_driver_t * loopback_driver_ctl = NULL; | ||||
int replace_registry = 0; | int replace_registry = 0; | ||||
const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" | const char *options = "-d:X:I:P:uvshVrRL:STFl:t:mn:p:" | ||||
"a:" | |||||
#ifdef __linux__ | #ifdef __linux__ | ||||
"c:" | "c:" | ||||
#endif | #endif | ||||
@@ -234,6 +234,7 @@ int main(int argc, char** argv) | |||||
{ "version", 0, 0, 'V' }, | { "version", 0, 0, 'V' }, | ||||
{ "silent", 0, 0, 's' }, | { "silent", 0, 0, 's' }, | ||||
{ "sync", 0, 0, 'S' }, | { "sync", 0, 0, 'S' }, | ||||
{ "autoconnect", 1, 0, 'a' }, | |||||
{ 0, 0, 0, 0 } | { 0, 0, 0, 0 } | ||||
}; | }; | ||||
@@ -296,6 +297,26 @@ int main(int argc, char** argv) | |||||
break; | break; | ||||
#endif | #endif | ||||
case 'a': | |||||
param = jackctl_get_parameter(server_parameters, "self-connect-mode"); | |||||
if (param != NULL) { | |||||
bool value_valid = false; | |||||
for (uint32_t k=0; k<jackctl_parameter_get_enum_constraints_count( param ); k++ ) { | |||||
value = jackctl_parameter_get_enum_constraint_value( param, k ); | |||||
if( value.c == optarg[0] ) | |||||
value_valid = true; | |||||
} | |||||
if( value_valid ) { | |||||
value.c = optarg[0]; | |||||
jackctl_parameter_set_value(param, &value); | |||||
} else { | |||||
usage(stdout); | |||||
goto destroy_server; | |||||
} | |||||
} | |||||
break; | |||||
case 'd': | case 'd': | ||||
master_driver_name = optarg; | master_driver_name = optarg; | ||||
break; | break; | ||||