21 #include "JackSystemDeps.h"
22 #include "JackDriverLoader.h"
23 #include "JackConstants.h"
24 #include "JackError.h"
39 char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1];
41 for (i = 0; i < desc->
nparams; i++) {
43 case JackDriverParamInt:
44 sprintf (arg_default,
"%" "i", desc->
params[i].
value.i);
46 case JackDriverParamUInt:
47 sprintf (arg_default,
"%" "u", desc->
params[i].
value.ui);
49 case JackDriverParamChar:
50 sprintf (arg_default,
"%c", desc->
params[i].
value.c);
52 case JackDriverParamString:
54 sprintf (arg_default,
"%s", desc->
params[i].
value.str);
56 sprintf (arg_default,
"none");
59 case JackDriverParamBool:
60 sprintf (arg_default,
"%s", desc->
params[i].
value.i ?
"true" :
"false");
64 fprintf(file,
"\t-%c, --%s \t%s (default: %s)\n",
73 jack_print_driver_param_usage (
jack_driver_desc_t* desc,
unsigned long param, FILE *file)
75 fprintf (file,
"Usage information for the '%s' parameter for driver '%s':\n",
80 SERVER_EXPORT
void jack_free_driver_params(
JSList * driver_params)
82 JSList*node_ptr = driver_params;
86 next_node_ptr = node_ptr->next;
89 node_ptr = next_node_ptr;
96 struct option * long_options;
97 char* options, * options_ptr;
100 unsigned int param_index;
110 if (strcmp (argv[1],
"-h") == 0 || strcmp (argv[1],
"--help") == 0) {
112 for (i = 0; i < desc->
nparams; i++) {
113 if (strcmp (desc->
params[i].
name, argv[2]) == 0) {
114 jack_print_driver_param_usage (desc, i, stdout);
119 fprintf (stderr,
"jackd: unknown option '%s' "
120 "for driver '%s'\n", argv[2],
124 jack_log(
"Parameters for driver '%s' (all parameters are optional):", desc->
name);
125 jack_print_driver_options (desc, stdout);
130 options = (
char*)calloc (desc->
nparams * 3 + 1, sizeof (
char));
133 options_ptr = options;
134 for (i = 0; i < desc->
nparams; i++) {
138 long_options[i].flag = NULL;
140 long_options[i].has_arg = optional_argument;
146 while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
148 if (opt ==
':' || opt ==
'?') {
150 fprintf (stderr,
"Missing option to argument '%c'\n", optopt);
152 fprintf (stderr,
"Unknownage with option '%c'\n", optopt);
155 fprintf (stderr,
"Options for driver '%s':\n", desc->
name);
156 jack_print_driver_options (desc, stderr);
160 for (param_index = 0; param_index < desc->
nparams; param_index++) {
169 if (!optarg && optind < argc &&
170 strlen(argv[optind]) &&
171 argv[optind][0] !=
'-') {
172 optarg = argv[optind];
177 case JackDriverParamInt:
178 driver_param->value.i = atoi(optarg);
180 case JackDriverParamUInt:
181 driver_param->value.ui = strtoul(optarg, NULL, 10);
183 case JackDriverParamChar:
184 driver_param->value.c = optarg[0];
186 case JackDriverParamString:
187 strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
189 case JackDriverParamBool:
190 if (strcasecmp(
"false", optarg) == 0 ||
191 strcasecmp(
"off", optarg) == 0 ||
192 strcasecmp(
"no", optarg) == 0 ||
193 strcasecmp(
"0", optarg) == 0 ||
194 strcasecmp(
"(null)", optarg) == 0 ) {
195 driver_param->value.i =
false;
197 driver_param->value.i =
true;
202 if (desc->
params[param_index].
type == JackDriverParamBool) {
203 driver_param->value.i =
true;
205 driver_param->value = desc->
params[param_index].
value;
209 params = jack_slist_append (params, driver_param);
222 jackctl_parse_driver_params(
jackctl_driver *driver_ptr,
int argc,
char* argv[])
224 struct option* long_options;
225 char* options, * options_ptr;
237 if (driver_params == NULL) {
244 if (strcmp (argv[1],
"-h") == 0 || strcmp (argv[1],
"--help") == 0) {
246 for (i = 0; i < desc->
nparams; i++) {
247 if (strcmp (desc->
params[i].
name, argv[2]) == 0) {
248 jack_print_driver_param_usage (desc, i, stdout);
253 fprintf (stderr,
"jackd: unknown option '%s' "
254 "for driver '%s'\n", argv[2],
258 jack_log(
"Parameters for driver '%s' (all parameters are optional):", desc->
name);
259 jack_print_driver_options (desc, stdout);
264 options = (
char*)calloc (desc->
nparams * 3 + 1, sizeof (
char));
267 options_ptr = options;
268 for (i = 0; i < desc->
nparams; i++) {
272 long_options[
i].flag = NULL;
274 long_options[
i].has_arg = optional_argument;
280 while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
282 if (opt ==
':' || opt ==
'?') {
284 fprintf (stderr,
"Missing option to argument '%c'\n", optopt);
286 fprintf (stderr,
"Unknownage with option '%c'\n", optopt);
289 fprintf (stderr,
"Options for driver '%s':\n", desc->
name);
290 jack_print_driver_options(desc, stderr);
294 node_ptr = (
JSList *)driver_params;
300 node_ptr = node_ptr->next;
303 if (!optarg && optind < argc &&
304 strlen(argv[optind]) &&
305 argv[optind][0] !=
'-') {
306 optarg = argv[optind];
311 case JackDriverParamInt:
312 value.i = atoi(optarg);
315 case JackDriverParamUInt:
316 value.ui = strtoul(optarg, NULL, 10);
319 case JackDriverParamChar:
323 case JackDriverParamString:
324 strncpy(value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
327 case JackDriverParamBool:
328 if (strcasecmp(
"false", optarg) == 0 ||
329 strcasecmp(
"off", optarg) == 0 ||
330 strcasecmp(
"no", optarg) == 0 ||
331 strcasecmp(
"0", optarg) == 0 ||
332 strcasecmp(
"(null)", optarg) == 0 ) {
356 jack_find_driver_descriptor (
JSList * drivers,
const char* name)
361 for (node = drivers; node; node = jack_slist_next (node)) {
364 if (strcmp (desc->
name, name) != 0) {
375 jack_get_descriptor (
JSList * drivers,
const char* sofile,
const char* symbol)
378 JackDriverDescFunction so_get_descriptor = NULL;
389 const char* driver_dir;
391 if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
395 char temp_driver_dir1[512];
396 char temp_driver_dir2[512];
397 if (3 < GetModuleFileName(NULL, temp_driver_dir1, 512)) {
398 char *p = strrchr(temp_driver_dir1,
'\\');
399 if (p && (p != temp_driver_dir1))
402 GetCurrentDirectory(512, temp_driver_dir1);
404 GetCurrentDirectory(512, temp_driver_dir1);
406 sprintf(temp_driver_dir2,
"%s/%s", temp_driver_dir1, ADDON_DIR);
407 driver_dir = temp_driver_dir2;
409 driver_dir = ADDON_DIR;
413 int len = strlen(driver_dir) + 1 + strlen(sofile) + 1;
414 filename = (
char*)malloc(len);
415 snprintf(filename, len,
"%s/%s", driver_dir, sofile);
417 if ((dlhandle = LoadDriverModule(filename)) == NULL) {
419 jack_error (
"could not open driver .dll '%s': %ld", filename, GetLastError());
421 jack_error (
"could not open driver .so '%s': %s", filename, dlerror());
428 so_get_descriptor = (JackDriverDescFunction)GetDriverProc(dlhandle, symbol);
431 if ((so_get_descriptor == NULL) && (dlerr = GetLastError()) != 0) {
432 jack_error(
"jack_get_descriptor : dll is not a driver, err = %ld", dlerr);
434 if ((so_get_descriptor == NULL) && (dlerr = dlerror ()) != NULL) {
435 jack_error(
"jack_get_descriptor err = %s", dlerr);
438 UnloadDriverModule(dlhandle);
443 if ((descriptor = so_get_descriptor ()) == NULL) {
444 jack_error(
"driver from '%s' returned NULL descriptor", filename);
445 UnloadDriverModule(dlhandle);
451 if ((err = UnloadDriverModule(dlhandle)) == 0) {
452 jack_error (
"error closing driver .so '%s': %ld", filename, GetLastError ());
455 if ((err = UnloadDriverModule(dlhandle)) != 0) {
456 jack_error (
"error closing driver .so '%s': %s", filename, dlerror ());
461 for (node = drivers; node; node = jack_slist_next (node)) {
464 if (strcmp(descriptor->
name, other_descriptor->
name) == 0) {
465 jack_error(
"the drivers in '%s' and '%s' both have the name '%s'; using the first",
466 other_descriptor->
file, filename, other_descriptor->
name);
473 strncpy(descriptor->
file, filename, JACK_PATH_MAX);
478 static bool check_symbol(
const char* sofile,
const char* symbol)
482 const char* driver_dir;
484 if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
488 char temp_driver_dir1[512];
489 char temp_driver_dir2[512];
490 if (3 < GetModuleFileName(NULL, temp_driver_dir1, 512)) {
491 char *p = strrchr(temp_driver_dir1,
'\\');
492 if (p && (p != temp_driver_dir1))
495 GetCurrentDirectory(512, temp_driver_dir1);
497 GetCurrentDirectory(512, temp_driver_dir1);
499 snprintf(temp_driver_dir2,
sizeof(temp_driver_dir2),
"%s/%s", temp_driver_dir1, ADDON_DIR);
500 driver_dir = temp_driver_dir2;
502 driver_dir = ADDON_DIR;
506 int len = strlen(driver_dir) + 1 + strlen(sofile) + 1;
507 char* filename = (
char*)malloc(len);
508 snprintf(filename, len,
"%s/%s", driver_dir, sofile);
510 if ((dlhandle = LoadDriverModule(filename)) == NULL) {
512 jack_error (
"could not open component .dll '%s': %ld", filename, GetLastError());
514 jack_error (
"could not open component .so '%s': %s", filename, dlerror());
517 res = (GetDriverProc(dlhandle, symbol)) ?
true :
false;
518 UnloadDriverModule(dlhandle);
528 jack_drivers_load (
JSList * drivers) {
530 char driver_dir_storage[512];
531 char dll_filename[512];
532 WIN32_FIND_DATA filedata;
534 const char* ptr = NULL;
535 JSList* driver_list = NULL;
538 if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
540 if (3 < GetModuleFileName(NULL, driver_dir_storage, 512)) {
541 char *p = strrchr(driver_dir_storage,
'\\');
542 if (p && (p != driver_dir_storage))
545 GetCurrentDirectory(512, driver_dir_storage);
547 GetCurrentDirectory(512, driver_dir_storage);
549 strcat(driver_dir_storage,
"/");
550 strcat(driver_dir_storage, ADDON_DIR);
551 driver_dir = driver_dir_storage;
554 snprintf(dll_filename,
sizeof(dll_filename),
"%s/*.dll", driver_dir);
556 file = (HANDLE )FindFirstFile(dll_filename, &filedata);
558 if (file == INVALID_HANDLE_VALUE) {
565 if (strncmp (
"jack_", filedata.cFileName, 5) != 0) {
569 ptr = strrchr (filedata.cFileName,
'.');
574 if (strncmp (
"dll", ptr, 3) != 0) {
579 if (check_symbol(filedata.cFileName,
"jack_internal_initialize")) {
583 desc = jack_get_descriptor (drivers, filedata.cFileName,
"driver_get_descriptor");
585 driver_list = jack_slist_append (driver_list, desc);
587 jack_error (
"jack_get_descriptor returns null for \'%s\'", filedata.cFileName);
590 }
while (FindNextFile(file, &filedata));
593 jack_error (
"could not find any drivers in %s!", driver_dir);
603 jack_drivers_load (
JSList * drivers) {
604 struct dirent * dir_entry;
608 JSList* driver_list = NULL;
611 const char* driver_dir;
612 if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
613 driver_dir = ADDON_DIR;
618 dir_stream = opendir (driver_dir);
620 jack_error (
"could not open driver directory %s: %s",
621 driver_dir, strerror (errno));
625 while ((dir_entry = readdir(dir_stream))) {
628 if (strncmp (
"jack_", dir_entry->d_name, 5) != 0) {
632 ptr = strrchr (dir_entry->d_name,
'.');
637 if (strncmp (
"so", ptr, 2) != 0) {
642 if (check_symbol(dir_entry->d_name,
"jack_internal_initialize")) {
646 desc = jack_get_descriptor (drivers, dir_entry->d_name,
"driver_get_descriptor");
648 driver_list = jack_slist_append (driver_list, desc);
650 jack_error (
"jack_get_descriptor returns null for \'%s\'", dir_entry->d_name);
654 err = closedir (dir_stream);
656 jack_error (
"error closing driver directory %s: %s",
657 driver_dir, strerror (errno));
661 jack_error (
"could not find any drivers in %s!", driver_dir);
673 jack_internals_load (
JSList * internals) {
675 char driver_dir_storage[512];
676 char dll_filename[512];
677 WIN32_FIND_DATA filedata;
679 const char* ptr = NULL;
680 JSList* driver_list = NULL;
683 if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
685 if (3 < GetModuleFileName(NULL, driver_dir_storage, 512)) {
686 char *p = strrchr(driver_dir_storage,
'\\');
687 if (p && (p != driver_dir_storage))
690 GetCurrentDirectory(512, driver_dir_storage);
692 GetCurrentDirectory(512, driver_dir_storage);
694 strcat(driver_dir_storage,
"/");
695 strcat(driver_dir_storage, ADDON_DIR);
696 driver_dir = driver_dir_storage;
699 snprintf(dll_filename,
sizeof(dll_filename),
"%s/*.dll", driver_dir);
701 file = (HANDLE )FindFirstFile(dll_filename, &filedata);
703 if (file == INVALID_HANDLE_VALUE) {
704 jack_error(
"could not open driver directory %s", driver_dir);
710 ptr = strrchr (filedata.cFileName,
'.');
715 if (strncmp (
"dll", ptr, 3) != 0) {
720 if (!check_symbol(filedata.cFileName,
"jack_internal_initialize")) {
724 desc = jack_get_descriptor (internals, filedata.cFileName,
"jack_get_descriptor");
726 driver_list = jack_slist_append (driver_list, desc);
728 jack_error (
"jack_get_descriptor returns null for \'%s\'", filedata.cFileName);
731 }
while (FindNextFile(file, &filedata));
734 jack_error (
"could not find any internals in %s!", driver_dir);
744 jack_internals_load (
JSList * internals) {
745 struct dirent * dir_entry;
749 JSList* driver_list = NULL;
752 const char* driver_dir;
753 if ((driver_dir = getenv(
"JACK_DRIVER_DIR")) == 0) {
754 driver_dir = ADDON_DIR;
759 dir_stream = opendir (driver_dir);
761 jack_error (
"could not open driver directory %s: %s\n",
762 driver_dir, strerror (errno));
766 while ((dir_entry = readdir(dir_stream))) {
768 ptr = strrchr (dir_entry->d_name,
'.');
773 if (strncmp (
"so", ptr, 2) != 0) {
778 if (!check_symbol(dir_entry->d_name,
"jack_internal_initialize")) {
782 desc = jack_get_descriptor (internals, dir_entry->d_name,
"jack_get_descriptor");
784 driver_list = jack_slist_append (driver_list, desc);
786 jack_error (
"jack_get_descriptor returns null for \'%s\'", dir_entry->d_name);
790 err = closedir (dir_stream);
792 jack_error (
"error closing internal directory %s: %s\n",
793 driver_dir, strerror (errno));
797 jack_error (
"could not find any internals in %s!", driver_dir);
817 fHandle = LoadDriverModule (driver_desc->
file);
819 if (fHandle == NULL) {
821 if ((errstr = GetLastError ()) != 0) {
824 if ((errstr = dlerror ()) != 0) {
829 jack_error (
"bizarre error loading driver shared object %s", driver_desc->
file);
834 fInitialize = (driverInitialize)GetDriverProc(fHandle,
"driver_initialize");
837 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) {
839 if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) {
841 jack_error(
"no initialize function in shared object %s\n", driver_desc->
file);
845 fBackend = fInitialize(engine, synchro, params);
849 JackDriverInfo::~JackDriverInfo()
853 UnloadDriverModule(fHandle);
858 jack_driver_descriptor_construct(
860 jack_driver_type_t type,
861 const char * description,
865 size_t description_len;
868 name_len = strlen(name);
869 description_len = strlen(description);
871 if (name_len >
sizeof(desc_ptr->
name) - 1 ||
872 description_len >
sizeof(desc_ptr->
desc) - 1) {
878 if (desc_ptr == NULL) {
879 jack_error(
"calloc() failed to allocate memory for driver descriptor struct");
883 memcpy(desc_ptr->
name, name, name_len + 1);
884 memcpy(desc_ptr->
desc, description, description_len + 1);
887 desc_ptr->
type = type;
889 if (filler_ptr != NULL) {
890 filler_ptr->size = 0;
898 jack_driver_descriptor_add_parameter(
903 jack_driver_param_type_t type,
906 const char* short_desc,
907 const char* long_desc)
910 size_t short_desc_len;
911 size_t long_desc_len;
915 name_len = strlen(name);
916 short_desc_len = strlen(short_desc);
918 if (long_desc != NULL) {
919 long_desc_len = strlen(long_desc);
921 long_desc = short_desc;
922 long_desc_len = short_desc_len;
925 if (name_len >
sizeof(param_ptr->
name) - 1 ||
926 short_desc_len >
sizeof(param_ptr->
short_desc) - 1 ||
927 long_desc_len >
sizeof(param_ptr->
long_desc) - 1) {
932 if (desc_ptr->
nparams == filler_ptr->size) {
933 newsize = filler_ptr->size + 20;
935 if (param_ptr == NULL) {
936 jack_error(
"realloc() failed for parameter array of %zu elements", newsize);
939 filler_ptr->size = newsize;
940 desc_ptr->
params = param_ptr;
943 assert(desc_ptr->
nparams < filler_ptr->size);
946 memcpy(param_ptr->
name, name, name_len + 1);
948 param_ptr->
type = type;
949 param_ptr->
value = *value_ptr;
951 memcpy(param_ptr->
short_desc, short_desc, short_desc_len + 1);
952 memcpy(param_ptr->
long_desc, long_desc, long_desc_len + 1);