|
|
@@ -1,6 +1,7 @@ |
|
|
|
/* |
|
|
|
Copyright (C) 2001-2003 Paul Davis |
|
|
|
Copyright (C) 2004-2008 Grame |
|
|
|
Copyright (C) 2011 John Emmas |
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify |
|
|
|
it under the terms of the GNU Lesser General Public License as published by |
|
|
@@ -18,9 +19,297 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
#ifndef JACK_LOCATION |
|
|
|
#include "config.h" |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "JackChannel.h" |
|
|
|
#include "JackLibGlobals.h" |
|
|
|
#include "JackServerLaunch.h" |
|
|
|
#include "JackPlatformPlug.h" |
|
|
|
|
|
|
|
int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status) |
|
|
|
using namespace Jack; |
|
|
|
|
|
|
|
#if defined(WIN32) && !defined(__CYGWIN__) |
|
|
|
|
|
|
|
#include <shlobj.h> |
|
|
|
#include <process.h> |
|
|
|
#include <string.h> |
|
|
|
#include <fcntl.h> |
|
|
|
#include <io.h> |
|
|
|
|
|
|
|
#ifdef _MSC_VER |
|
|
|
|
|
|
|
static char* |
|
|
|
find_path_to_jackdrc(char *path_to_jackdrc) |
|
|
|
{ |
|
|
|
char user_jackdrc[1024]; |
|
|
|
char *ptr = NULL; |
|
|
|
char *ret = NULL; |
|
|
|
|
|
|
|
user_jackdrc[0] = user_jackdrc[1] = 0; // Initialise |
|
|
|
|
|
|
|
if (S_OK == SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, user_jackdrc)) |
|
|
|
{ |
|
|
|
int fh; |
|
|
|
|
|
|
|
// The above call should have given us the path to the user's home folder |
|
|
|
char* pos; |
|
|
|
char ch = user_jackdrc[strlen(user_jackdrc)-1]; |
|
|
|
|
|
|
|
if (('/' != ch) && ('\\' != ch)) |
|
|
|
strcat(user_jackdrc, "\\"); |
|
|
|
|
|
|
|
if (user_jackdrc[1] == ':') |
|
|
|
{ |
|
|
|
// Assume we have a valid path |
|
|
|
strcat(user_jackdrc, ".jackdrc"); |
|
|
|
strcpy(path_to_jackdrc, user_jackdrc); |
|
|
|
|
|
|
|
ret = path_to_jackdrc; |
|
|
|
} |
|
|
|
else |
|
|
|
path_to_jackdrc[0] = '\0'; |
|
|
|
} |
|
|
|
else |
|
|
|
path_to_jackdrc[0] = '\0'; |
|
|
|
|
|
|
|
return (ret); |
|
|
|
} |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
static char* |
|
|
|
find_path_to_jackdrc(char *path_to_jackdrc) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
/* 'start_server_aux()' - this function might need to be modified (though probably |
|
|
|
* not) to cope with compilers other than MSVC (e.g. MinGW). The function |
|
|
|
* 'find_path_to_jackdrc()' might also need to be written for MinGW, though for |
|
|
|
* Cygwin, JackPosixServerLaunch.cpp can be used instead of this file. |
|
|
|
*/ |
|
|
|
|
|
|
|
#include <direct.h> |
|
|
|
static int start_server_aux(const char* server_name) |
|
|
|
{ |
|
|
|
FILE* fp = 0; |
|
|
|
size_t pos = 0; |
|
|
|
size_t result = 0; |
|
|
|
int i = 0; |
|
|
|
int good = 0; |
|
|
|
int ret = 0; |
|
|
|
char* command = 0; |
|
|
|
char** argv = 0; |
|
|
|
char* p; |
|
|
|
char* back_slash; |
|
|
|
char* forward_slash; |
|
|
|
char arguments [256]; |
|
|
|
char buffer [MAX_PATH]; |
|
|
|
char filename [MAX_PATH]; |
|
|
|
char curr_wd [MAX_PATH]; |
|
|
|
char temp_wd [MAX_PATH]; |
|
|
|
|
|
|
|
curr_wd[0] = '\0'; |
|
|
|
if (find_path_to_jackdrc(filename)) |
|
|
|
fp = fopen(filename, "r"); |
|
|
|
|
|
|
|
/* if still not found, check old config name for backwards compatability */ |
|
|
|
/* JE - hopefully won't be needed for the Windows build |
|
|
|
if (!fp) { |
|
|
|
fp = fopen("/etc/jackd.conf", "r"); |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
if (fp) { |
|
|
|
arguments[0] = '\0'; |
|
|
|
|
|
|
|
fgets(filename, MAX_PATH, fp); |
|
|
|
_strlwr(filename); |
|
|
|
if (p = strstr(filename, ".exe")) { |
|
|
|
p += 4; |
|
|
|
*p = '\0'; |
|
|
|
pos = (size_t)(p - filename); |
|
|
|
fseek(fp, 0, SEEK_SET); |
|
|
|
|
|
|
|
if (command = (char*)malloc(pos+1)) |
|
|
|
ret = fread(command, 1, pos, fp); |
|
|
|
|
|
|
|
if (ret && !ferror(fp)) { |
|
|
|
command[pos] = '\0'; // NULL terminator |
|
|
|
back_slash = strrchr(command, '\\'); |
|
|
|
forward_slash = strrchr(command, '/'); |
|
|
|
if (back_slash > forward_slash) |
|
|
|
p = back_slash + 1; |
|
|
|
else |
|
|
|
p = forward_slash + 1; |
|
|
|
|
|
|
|
strcpy(buffer, p); |
|
|
|
while (ret != 0 && ret != EOF) { |
|
|
|
strcat(arguments, buffer); |
|
|
|
strcat(arguments, " "); |
|
|
|
ret = fscanf(fp, "%s", buffer); |
|
|
|
} |
|
|
|
|
|
|
|
if (strlen(arguments) > 0) { |
|
|
|
good = 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fclose(fp); |
|
|
|
} |
|
|
|
|
|
|
|
if (!good) { |
|
|
|
strcpy(buffer, JACK_LOCATION "/jackd.exe"); |
|
|
|
command = (char*)malloc((strlen(buffer))+1); |
|
|
|
strcpy(command, buffer); |
|
|
|
strncpy(arguments, "jackd.exe -S -d " JACK_DEFAULT_DRIVER, 255); |
|
|
|
} |
|
|
|
|
|
|
|
int buffer_termination; |
|
|
|
argv = (char**)malloc(255); |
|
|
|
pos = 0; |
|
|
|
|
|
|
|
while (1) { |
|
|
|
/* insert -T and -n server_name in front of arguments */ |
|
|
|
if (i == 1) { |
|
|
|
argv[i] = (char*)malloc(strlen ("-T") + 1); |
|
|
|
strcpy (argv[i++], "-T"); |
|
|
|
if (server_name) { |
|
|
|
size_t optlen = strlen("-n"); |
|
|
|
char* buf = (char*)malloc(optlen + strlen(server_name) + 1); |
|
|
|
strcpy(buf, "-n"); |
|
|
|
strcpy(buf + optlen, server_name); |
|
|
|
argv[i++] = buf; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Only get the next character if there's more than 1 character |
|
|
|
if ((pos < strlen(arguments)) && (arguments[pos+1]) && (arguments[pos+1] != ' ')) { |
|
|
|
strncpy(buffer, arguments + pos++, 1); |
|
|
|
buffer_termination = 1; |
|
|
|
} else { |
|
|
|
buffer[0] = '\0'; |
|
|
|
buffer_termination = 0; |
|
|
|
} |
|
|
|
|
|
|
|
buffer[1] = '\0'; |
|
|
|
if (buffer[0] == '\"') |
|
|
|
result = strcspn(arguments + pos, "\""); |
|
|
|
else |
|
|
|
result = strcspn(arguments + pos, " "); |
|
|
|
|
|
|
|
if (0 == result) |
|
|
|
break; |
|
|
|
else |
|
|
|
{ |
|
|
|
strcat(buffer, arguments + pos); |
|
|
|
|
|
|
|
// Terminate the buffer |
|
|
|
buffer[result + buffer_termination] = '\0'; |
|
|
|
if (buffer[0] == '\"') { |
|
|
|
strcat(buffer, "\""); |
|
|
|
++result; |
|
|
|
} |
|
|
|
|
|
|
|
argv[i] = (char*)malloc(strlen(buffer) + 1); |
|
|
|
strcpy(argv[i], buffer); |
|
|
|
pos += (result + 1); |
|
|
|
++i; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
argv[i] = 0; |
|
|
|
|
|
|
|
#ifdef SUPPORT_PRE_1_9_8_SERVER |
|
|
|
// Get the current working directory |
|
|
|
if (_getcwd(curr_wd, MAX_PATH)) { |
|
|
|
strcpy(temp_wd, command); |
|
|
|
back_slash = strrchr(temp_wd, '\\'); |
|
|
|
forward_slash = strrchr(temp_wd, '/'); |
|
|
|
if (back_slash > forward_slash) |
|
|
|
p = back_slash; |
|
|
|
else |
|
|
|
p = forward_slash; |
|
|
|
*p = '\0'; |
|
|
|
|
|
|
|
// Accommodate older versions of Jack (pre v1.9.8) which |
|
|
|
// might need to be started from their installation folder. |
|
|
|
_chdir(temp_wd); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
ret = _spawnv(_P_NOWAIT, command, argv); |
|
|
|
Sleep(2500); // Give the server time to launch |
|
|
|
|
|
|
|
if ((-1) == ret) |
|
|
|
fprintf(stderr, "Execution of JACK server (command = \"%s\") failed: %s\n", command, strerror(errno)); |
|
|
|
|
|
|
|
if (strlen(curr_wd)) { |
|
|
|
// Change the cwd back to its original setting |
|
|
|
_chdir(curr_wd); |
|
|
|
} |
|
|
|
|
|
|
|
if (command) |
|
|
|
free(command); |
|
|
|
|
|
|
|
if (argv) { |
|
|
|
for (i = 0; argv[i] != 0; i++) |
|
|
|
free (argv[i]); |
|
|
|
|
|
|
|
free(argv); |
|
|
|
} |
|
|
|
|
|
|
|
return (ret == (-1) ? false : true); |
|
|
|
} |
|
|
|
|
|
|
|
static int start_server(const char* server_name, jack_options_t options) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
if ((options & JackNoStartServer) || getenv("JACK_NO_START_SERVER")) { |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
return (((-1) != (start_server_aux(server_name)) ? 0 : (-1))); |
|
|
|
} |
|
|
|
|
|
|
|
static int server_connect(const char* server_name) |
|
|
|
{ |
|
|
|
JackClientChannel channel; |
|
|
|
int res = channel.ServerCheck(server_name); |
|
|
|
channel.Close(); |
|
|
|
JackSleep(2000); // Added by JE - 02-01-2009 (gives |
|
|
|
// the channel some time to close) |
|
|
|
return res; |
|
|
|
} |
|
|
|
|
|
|
|
int try_start_server(jack_varargs_t* va, jack_options_t options, jack_status_t* status) |
|
|
|
{ |
|
|
|
if (server_connect(va->server_name) < 0) { |
|
|
|
int trys; |
|
|
|
if (start_server(va->server_name, options)) { |
|
|
|
int my_status1 = *status | JackFailure | JackServerFailed; |
|
|
|
*status = (jack_status_t)my_status1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
trys = 5; |
|
|
|
do { |
|
|
|
Sleep(1000); |
|
|
|
if (--trys < 0) { |
|
|
|
int my_status1 = *status | JackFailure | JackServerFailed; |
|
|
|
*status = (jack_status_t)my_status1; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} while (server_connect(va->server_name) < 0); |
|
|
|
int my_status1 = *status | JackServerStarted; |
|
|
|
*status = (jack_status_t)my_status1; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
#endif // WIN32 && !__CYGWIN__ |
|
|
|
|