Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2001-2005 Paul Davis 00003 Copyright (C) 2004-2008 Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 00019 */ 00020 00021 #include "JackSystemDeps.h" 00022 #include "JackDriverLoader.h" 00023 #include "JackConstants.h" 00024 #include "JackError.h" 00025 #include <getopt.h> 00026 #include <stdio.h> 00027 #include <errno.h> 00028 00029 #ifndef WIN32 00030 #include <dirent.h> 00031 #endif 00032 00033 jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t * driver); 00034 00035 SERVER_EXPORT void jack_print_driver_options (jack_driver_desc_t* desc, FILE* file) 00036 { 00037 unsigned long i; 00038 char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1]; 00039 00040 for (i = 0; i < desc->nparams; i++) { 00041 switch (desc->params[i].type) { 00042 case JackDriverParamInt: 00043 sprintf (arg_default, "%" "i", desc->params[i].value.i); 00044 break; 00045 case JackDriverParamUInt: 00046 sprintf (arg_default, "%" "u", desc->params[i].value.ui); 00047 break; 00048 case JackDriverParamChar: 00049 sprintf (arg_default, "%c", desc->params[i].value.c); 00050 break; 00051 case JackDriverParamString: 00052 if (desc->params[i].value.str && strcmp (desc->params[i].value.str, "") != 0) 00053 sprintf (arg_default, "%s", desc->params[i].value.str); 00054 else 00055 sprintf (arg_default, "none"); 00056 break; 00057 case JackDriverParamBool: 00058 sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false"); 00059 break; 00060 } 00061 00062 fprintf (file, "\t-%c, --%s \t%s (default: %s)\n", 00063 desc->params[i].character, 00064 desc->params[i].name, 00065 desc->params[i].long_desc, 00066 arg_default); 00067 } 00068 } 00069 00070 static void 00071 jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file) 00072 { 00073 fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n", 00074 desc->params[param].name, desc->name); 00075 fprintf (file, "%s\n", desc->params[param].long_desc); 00076 } 00077 00078 SERVER_EXPORT void jack_free_driver_params(JSList * driver_params) 00079 { 00080 JSList *node_ptr = driver_params; 00081 JSList *next_node_ptr; 00082 00083 while (node_ptr) { 00084 next_node_ptr = node_ptr->next; 00085 free(node_ptr->data); 00086 free(node_ptr); 00087 node_ptr = next_node_ptr; 00088 } 00089 } 00090 00091 int 00092 jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr) 00093 { 00094 struct option * long_options; 00095 char * options, * options_ptr; 00096 unsigned long i; 00097 int opt; 00098 unsigned int param_index; 00099 JSList * params = NULL; 00100 jack_driver_param_t * driver_param; 00101 00102 if (argc <= 1) { 00103 *param_ptr = NULL; 00104 return 0; 00105 } 00106 00107 /* check for help */ 00108 if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { 00109 if (argc > 2) { 00110 for (i = 0; i < desc->nparams; i++) { 00111 if (strcmp (desc->params[i].name, argv[2]) == 0) { 00112 jack_print_driver_param_usage (desc, i, stdout); 00113 return 1; 00114 } 00115 } 00116 00117 fprintf (stderr, "jackd: unknown option '%s' " 00118 "for driver '%s'\n", argv[2], 00119 desc->name); 00120 } 00121 00122 printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name); 00123 jack_print_driver_options (desc, stdout); 00124 return 1; 00125 } 00126 00127 /* set up the stuff for getopt */ 00128 options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char)); 00129 long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option)); 00130 00131 options_ptr = options; 00132 for (i = 0; i < desc->nparams; i++) { 00133 sprintf (options_ptr, "%c::", desc->params[i].character); 00134 options_ptr += 3; 00135 long_options[i].name = desc->params[i].name; 00136 long_options[i].flag = NULL; 00137 long_options[i].val = desc->params[i].character; 00138 long_options[i].has_arg = optional_argument; 00139 } 00140 00141 /* create the params */ 00142 optind = 0; 00143 opterr = 0; 00144 while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { 00145 00146 if (opt == ':' || opt == '?') { 00147 if (opt == ':') { 00148 fprintf (stderr, "Missing option to argument '%c'\n", optopt); 00149 } else { 00150 fprintf (stderr, "Unknownage with option '%c'\n", optopt); 00151 } 00152 00153 fprintf (stderr, "Options for driver '%s':\n", desc->name); 00154 jack_print_driver_options (desc, stderr); 00155 return 1; 00156 } 00157 00158 for (param_index = 0; param_index < desc->nparams; param_index++) { 00159 if (opt == desc->params[param_index].character) { 00160 break; 00161 } 00162 } 00163 00164 driver_param = (jack_driver_param_t*)calloc (1, sizeof (jack_driver_param_t)); 00165 driver_param->character = desc->params[param_index].character; 00166 00167 if (!optarg && optind < argc && 00168 strlen(argv[optind]) && 00169 argv[optind][0] != '-') { 00170 optarg = argv[optind]; 00171 } 00172 00173 if (optarg) { 00174 switch (desc->params[param_index].type) { 00175 case JackDriverParamInt: 00176 driver_param->value.i = atoi (optarg); 00177 break; 00178 case JackDriverParamUInt: 00179 driver_param->value.ui = strtoul (optarg, NULL, 10); 00180 break; 00181 case JackDriverParamChar: 00182 driver_param->value.c = optarg[0]; 00183 break; 00184 case JackDriverParamString: 00185 strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); 00186 break; 00187 case JackDriverParamBool: 00188 00189 /* 00190 if (strcasecmp ("false", optarg) == 0 || 00191 strcasecmp ("off", optarg) == 0 || 00192 strcasecmp ("no", optarg) == 0 || 00193 strcasecmp ("0", optarg) == 0 || 00194 strcasecmp ("(null)", optarg) == 0 ) { 00195 */ 00196 // steph 00197 if (strcmp ("false", optarg) == 0 || 00198 strcmp ("off", optarg) == 0 || 00199 strcmp ("no", optarg) == 0 || 00200 strcmp ("0", optarg) == 0 || 00201 strcmp ("(null)", optarg) == 0 ) { 00202 driver_param->value.i = false; 00203 00204 } else { 00205 00206 driver_param->value.i = true; 00207 00208 } 00209 break; 00210 } 00211 } else { 00212 if (desc->params[param_index].type == JackDriverParamBool) { 00213 driver_param->value.i = true; 00214 } else { 00215 driver_param->value = desc->params[param_index].value; 00216 } 00217 } 00218 00219 params = jack_slist_append (params, driver_param); 00220 } 00221 00222 free (options); 00223 free (long_options); 00224 00225 if (param_ptr) 00226 *param_ptr = params; 00227 00228 return 0; 00229 } 00230 00231 SERVER_EXPORT int 00232 jackctl_parse_driver_params (jackctl_driver *driver_ptr, int argc, char* argv[]) 00233 { 00234 struct option * long_options; 00235 char * options, * options_ptr; 00236 unsigned long i; 00237 int opt; 00238 JSList * node_ptr; 00239 jackctl_parameter_t * param = NULL; 00240 union jackctl_parameter_value value; 00241 00242 if (argc <= 1) 00243 return 0; 00244 00245 const JSList * driver_params = jackctl_driver_get_parameters(driver_ptr); 00246 if (driver_params == NULL) 00247 return 1; 00248 00249 jack_driver_desc_t * desc = jackctl_driver_get_desc(driver_ptr); 00250 00251 /* check for help */ 00252 if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) { 00253 if (argc > 2) { 00254 for (i = 0; i < desc->nparams; i++) { 00255 if (strcmp (desc->params[i].name, argv[2]) == 0) { 00256 jack_print_driver_param_usage (desc, i, stdout); 00257 return 1; 00258 } 00259 } 00260 00261 fprintf (stderr, "jackd: unknown option '%s' " 00262 "for driver '%s'\n", argv[2], 00263 desc->name); 00264 } 00265 00266 printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name); 00267 jack_print_driver_options (desc, stdout); 00268 return 1; 00269 } 00270 00271 /* set up the stuff for getopt */ 00272 options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char)); 00273 long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option)); 00274 00275 options_ptr = options; 00276 for (i = 0; i < desc->nparams; i++) { 00277 sprintf (options_ptr, "%c::", desc->params[i].character); 00278 options_ptr += 3; 00279 long_options[i].name = desc->params[i].name; 00280 long_options[i].flag = NULL; 00281 long_options[i].val = desc->params[i].character; 00282 long_options[i].has_arg = optional_argument; 00283 } 00284 00285 /* create the params */ 00286 optind = 0; 00287 opterr = 0; 00288 while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) { 00289 00290 if (opt == ':' || opt == '?') { 00291 if (opt == ':') { 00292 fprintf (stderr, "Missing option to argument '%c'\n", optopt); 00293 } else { 00294 fprintf (stderr, "Unknownage with option '%c'\n", optopt); 00295 } 00296 00297 fprintf (stderr, "Options for driver '%s':\n", desc->name); 00298 jack_print_driver_options(desc, stderr); 00299 return 1; 00300 } 00301 00302 node_ptr = (JSList *)driver_params; 00303 while (node_ptr) { 00304 param = (jackctl_parameter_t*)node_ptr->data; 00305 if (opt == jackctl_parameter_get_id(param)) { 00306 break; 00307 } 00308 node_ptr = node_ptr->next; 00309 } 00310 00311 if (!optarg && optind < argc && 00312 strlen(argv[optind]) && 00313 argv[optind][0] != '-') { 00314 optarg = argv[optind]; 00315 } 00316 00317 if (optarg) { 00318 switch (jackctl_parameter_get_type(param)) { 00319 case JackDriverParamInt: 00320 value.i = atoi (optarg); 00321 jackctl_parameter_set_value(param, &value); 00322 break; 00323 case JackDriverParamUInt: 00324 value.ui = strtoul (optarg, NULL, 10); 00325 jackctl_parameter_set_value(param, &value); 00326 break; 00327 case JackDriverParamChar: 00328 value.c = optarg[0]; 00329 jackctl_parameter_set_value(param, &value); 00330 break; 00331 case JackDriverParamString: 00332 strncpy (value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX); 00333 jackctl_parameter_set_value(param, &value); 00334 break; 00335 case JackDriverParamBool: 00336 /* 00337 if (strcasecmp ("false", optarg) == 0 || 00338 strcasecmp ("off", optarg) == 0 || 00339 strcasecmp ("no", optarg) == 0 || 00340 strcasecmp ("0", optarg) == 0 || 00341 strcasecmp ("(null)", optarg) == 0 ) { 00342 */ 00343 // steph 00344 if (strcmp ("false", optarg) == 0 || 00345 strcmp ("off", optarg) == 0 || 00346 strcmp ("no", optarg) == 0 || 00347 strcmp ("0", optarg) == 0 || 00348 strcmp ("(null)", optarg) == 0 ) { 00349 value.i = false; 00350 } else { 00351 value.i = true; 00352 } 00353 jackctl_parameter_set_value(param, &value); 00354 break; 00355 } 00356 } else { 00357 if (jackctl_parameter_get_type(param) == JackParamBool) { 00358 value.i = true; 00359 } else { 00360 value = jackctl_parameter_get_default_value(param); 00361 } 00362 jackctl_parameter_set_value(param, &value); 00363 } 00364 } 00365 00366 free(options); 00367 free(long_options); 00368 return 0; 00369 } 00370 00371 jack_driver_desc_t * 00372 jack_find_driver_descriptor (JSList * drivers, const char * name) 00373 { 00374 jack_driver_desc_t * desc = 0; 00375 JSList * node; 00376 00377 for (node = drivers; node; node = jack_slist_next (node)) { 00378 desc = (jack_driver_desc_t *) node->data; 00379 00380 if (strcmp (desc->name, name) != 0) { 00381 desc = NULL; 00382 } else { 00383 break; 00384 } 00385 } 00386 00387 return desc; 00388 } 00389 00390 static jack_driver_desc_t * 00391 jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol) 00392 { 00393 jack_driver_desc_t * descriptor, * other_descriptor; 00394 JackDriverDescFunction so_get_descriptor = NULL; 00395 JSList * node; 00396 void * dlhandle; 00397 char * filename; 00398 #ifdef WIN32 00399 int dlerr; 00400 #else 00401 const char * dlerr; 00402 #endif 00403 00404 int err; 00405 const char* driver_dir; 00406 00407 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00408 // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path 00409 // for posix systems, it is absolute path of default driver dir 00410 #ifdef WIN32 00411 char temp_driver_dir1[512]; 00412 char temp_driver_dir2[512]; 00413 GetCurrentDirectory(512, temp_driver_dir1); 00414 sprintf(temp_driver_dir2, "%s/%s", temp_driver_dir1, ADDON_DIR); 00415 driver_dir = temp_driver_dir2; 00416 #else 00417 driver_dir = ADDON_DIR; 00418 #endif 00419 } 00420 00421 filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1); 00422 sprintf (filename, "%s/%s", driver_dir, sofile); 00423 00424 if ((dlhandle = LoadDriverModule(filename)) == NULL) { 00425 #ifdef WIN32 00426 jack_error ("could not open driver .dll '%s': %ld", filename, GetLastError()); 00427 #else 00428 jack_error ("could not open driver .so '%s': %s", filename, dlerror()); 00429 #endif 00430 00431 free(filename); 00432 return NULL; 00433 } 00434 00435 so_get_descriptor = (JackDriverDescFunction)GetDriverProc(dlhandle, symbol); 00436 00437 #ifdef WIN32 00438 if ((so_get_descriptor == NULL) && (dlerr = GetLastError()) != 0) { 00439 jack_log("jack_get_descriptor : dll is not a driver, err = %ld", dlerr); 00440 #else 00441 if ((so_get_descriptor == NULL) && (dlerr = dlerror ()) != NULL) { 00442 jack_log("jack_get_descriptor err = %s", dlerr); 00443 #endif 00444 00445 UnloadDriverModule(dlhandle); 00446 free(filename); 00447 return NULL; 00448 } 00449 00450 if ((descriptor = so_get_descriptor ()) == NULL) { 00451 jack_error("driver from '%s' returned NULL descriptor", filename); 00452 UnloadDriverModule(dlhandle); 00453 free(filename); 00454 return NULL; 00455 } 00456 00457 #ifdef WIN32 00458 if ((err = UnloadDriverModule(dlhandle)) == 0) { 00459 jack_error ("error closing driver .so '%s': %ld", filename, GetLastError ()); 00460 } 00461 #else 00462 if ((err = UnloadDriverModule(dlhandle)) != 0) { 00463 jack_error ("error closing driver .so '%s': %s", filename, dlerror ()); 00464 } 00465 #endif 00466 00467 /* check it doesn't exist already */ 00468 for (node = drivers; node; node = jack_slist_next (node)) { 00469 other_descriptor = (jack_driver_desc_t *) node->data; 00470 00471 if (strcmp(descriptor->name, other_descriptor->name) == 0) { 00472 jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first", 00473 other_descriptor->file, filename, other_descriptor->name); 00474 /* FIXME: delete the descriptor */ 00475 free(filename); 00476 return NULL; 00477 } 00478 } 00479 00480 strncpy(descriptor->file, filename, JACK_PATH_MAX); 00481 free(filename); 00482 return descriptor; 00483 } 00484 00485 static bool check_symbol(const char* sofile, const char* symbol) 00486 { 00487 void * dlhandle; 00488 bool res = false; 00489 const char* driver_dir; 00490 00491 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00492 // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path 00493 // for posix systems, it is absolute path of default driver dir 00494 #ifdef WIN32 00495 char temp_driver_dir1[512]; 00496 char temp_driver_dir2[512]; 00497 GetCurrentDirectory(512, temp_driver_dir1); 00498 sprintf(temp_driver_dir2, "%s/%s", temp_driver_dir1, ADDON_DIR); 00499 driver_dir = temp_driver_dir2; 00500 #else 00501 driver_dir = ADDON_DIR; 00502 #endif 00503 } 00504 00505 char* filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1); 00506 sprintf (filename, "%s/%s", driver_dir, sofile); 00507 00508 if ((dlhandle = LoadDriverModule(filename)) == NULL) { 00509 #ifdef WIN32 00510 jack_error ("could not open component .dll '%s': %ld", filename, GetLastError()); 00511 #else 00512 jack_error ("could not open component .so '%s': %s", filename, dlerror()); 00513 #endif 00514 } else { 00515 res = (GetDriverProc(dlhandle, symbol)) ? true : false; 00516 UnloadDriverModule(dlhandle); 00517 } 00518 00519 free(filename); 00520 return res; 00521 } 00522 00523 #ifdef WIN32 00524 00525 JSList * 00526 jack_drivers_load (JSList * drivers) { 00527 char * driver_dir; 00528 char driver_dir_storage[512]; 00529 char dll_filename[512]; 00530 WIN32_FIND_DATA filedata; 00531 HANDLE file; 00532 const char * ptr = NULL; 00533 JSList * driver_list = NULL; 00534 jack_driver_desc_t * desc; 00535 00536 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00537 // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path 00538 GetCurrentDirectory(512, driver_dir_storage); 00539 strcat(driver_dir_storage, "/"); 00540 strcat(driver_dir_storage, ADDON_DIR); 00541 driver_dir = driver_dir_storage; 00542 } 00543 00544 sprintf(dll_filename, "%s/*.dll", driver_dir); 00545 00546 file = (HANDLE )FindFirstFile(dll_filename, &filedata); 00547 00548 if (file == INVALID_HANDLE_VALUE) { 00549 jack_error("error invalid handle"); 00550 return NULL; 00551 } 00552 00553 do { 00554 ptr = strrchr (filedata.cFileName, '.'); 00555 if (!ptr) { 00556 continue; 00557 } 00558 ptr++; 00559 if (strncmp ("dll", ptr, 3) != 0) { 00560 continue; 00561 } 00562 00563 desc = jack_get_descriptor (drivers, filedata.cFileName, "driver_get_descriptor"); 00564 if (desc) { 00565 driver_list = jack_slist_append (driver_list, desc); 00566 } 00567 00568 } while (FindNextFile(file, &filedata)); 00569 00570 if (!driver_list) { 00571 jack_error ("could not find any drivers in %s!", driver_dir); 00572 return NULL; 00573 } 00574 00575 return driver_list; 00576 } 00577 00578 #else 00579 00580 JSList * 00581 jack_drivers_load (JSList * drivers) { 00582 struct dirent * dir_entry; 00583 DIR * dir_stream; 00584 const char * ptr; 00585 int err; 00586 JSList * driver_list = NULL; 00587 jack_driver_desc_t * desc; 00588 00589 const char* driver_dir; 00590 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00591 driver_dir = ADDON_DIR; 00592 } 00593 00594 /* search through the driver_dir and add get descriptors 00595 from the .so files in it */ 00596 dir_stream = opendir (driver_dir); 00597 if (!dir_stream) { 00598 jack_error ("could not open driver directory %s: %s", 00599 driver_dir, strerror (errno)); 00600 return NULL; 00601 } 00602 00603 while ((dir_entry = readdir(dir_stream))) { 00604 00605 /* check the filename is of the right format */ 00606 if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { 00607 continue; 00608 } 00609 00610 ptr = strrchr (dir_entry->d_name, '.'); 00611 if (!ptr) { 00612 continue; 00613 } 00614 ptr++; 00615 if (strncmp ("so", ptr, 2) != 0) { 00616 continue; 00617 } 00618 00619 desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor"); 00620 if (desc) { 00621 driver_list = jack_slist_append (driver_list, desc); 00622 } 00623 } 00624 00625 err = closedir (dir_stream); 00626 if (err) { 00627 jack_error ("error closing driver directory %s: %s", 00628 driver_dir, strerror (errno)); 00629 } 00630 00631 if (!driver_list) { 00632 jack_error ("could not find any drivers in %s!", driver_dir); 00633 return NULL; 00634 } 00635 00636 return driver_list; 00637 } 00638 00639 #endif 00640 00641 #ifdef WIN32 00642 00643 JSList * 00644 jack_internals_load (JSList * internals) { 00645 char * driver_dir; 00646 char driver_dir_storage[512]; 00647 char dll_filename[512]; 00648 WIN32_FIND_DATA filedata; 00649 HANDLE file; 00650 const char * ptr = NULL; 00651 JSList * driver_list = NULL; 00652 jack_driver_desc_t * desc; 00653 00654 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00655 // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path 00656 GetCurrentDirectory(512, driver_dir_storage); 00657 strcat(driver_dir_storage, "/"); 00658 strcat(driver_dir_storage, ADDON_DIR); 00659 driver_dir = driver_dir_storage; 00660 } 00661 00662 sprintf(dll_filename, "%s/*.dll", driver_dir); 00663 00664 file = (HANDLE )FindFirstFile(dll_filename, &filedata); 00665 00666 if (file == INVALID_HANDLE_VALUE) { 00667 jack_error("error"); 00668 return NULL; 00669 } 00670 00671 do { 00672 00673 ptr = strrchr (filedata.cFileName, '.'); 00674 if (!ptr) { 00675 continue; 00676 } 00677 ptr++; 00678 if (strncmp ("dll", ptr, 3) != 0) { 00679 continue; 00680 } 00681 00682 /* check if dll is an internal client */ 00683 if (!check_symbol(filedata.cFileName, "jack_internal_initialize")) { 00684 continue; 00685 } 00686 00687 desc = jack_get_descriptor (internals, filedata.cFileName, "jack_get_descriptor"); 00688 if (desc) { 00689 driver_list = jack_slist_append (driver_list, desc); 00690 } 00691 00692 } while (FindNextFile(file, &filedata)); 00693 00694 if (!driver_list) { 00695 jack_error ("could not find any internals in %s!", driver_dir); 00696 return NULL; 00697 } 00698 00699 return driver_list; 00700 } 00701 00702 #else 00703 00704 JSList * 00705 jack_internals_load (JSList * internals) { 00706 struct dirent * dir_entry; 00707 DIR * dir_stream; 00708 const char * ptr; 00709 int err; 00710 JSList * driver_list = NULL; 00711 jack_driver_desc_t * desc; 00712 00713 const char* driver_dir; 00714 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00715 driver_dir = ADDON_DIR; 00716 } 00717 00718 /* search through the driver_dir and add get descriptors 00719 from the .so files in it */ 00720 dir_stream = opendir (driver_dir); 00721 if (!dir_stream) { 00722 jack_error ("could not open driver directory %s: %s\n", 00723 driver_dir, strerror (errno)); 00724 return NULL; 00725 } 00726 00727 while ((dir_entry = readdir(dir_stream))) { 00728 00729 ptr = strrchr (dir_entry->d_name, '.'); 00730 if (!ptr) { 00731 continue; 00732 } 00733 ptr++; 00734 if (strncmp ("so", ptr, 2) != 0) { 00735 continue; 00736 } 00737 00738 /* check if dll is an internal client */ 00739 if (!check_symbol(dir_entry->d_name, "jack_internal_initialize")) { 00740 continue; 00741 } 00742 00743 desc = jack_get_descriptor (internals, dir_entry->d_name, "jack_get_descriptor"); 00744 if (desc) { 00745 driver_list = jack_slist_append (driver_list, desc); 00746 } 00747 } 00748 00749 err = closedir (dir_stream); 00750 if (err) { 00751 jack_error ("error closing internal directory %s: %s\n", 00752 driver_dir, strerror (errno)); 00753 } 00754 00755 if (!driver_list) { 00756 jack_error ("could not find any internals in %s!", driver_dir); 00757 return NULL; 00758 } 00759 00760 return driver_list; 00761 } 00762 00763 #endif 00764 00765 Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, 00766 Jack::JackLockedEngine* engine, 00767 Jack::JackSynchro* synchro, 00768 const JSList* params) 00769 { 00770 #ifdef WIN32 00771 int errstr; 00772 #else 00773 const char * errstr; 00774 #endif 00775 00776 fHandle = LoadDriverModule (driver_desc->file); 00777 00778 if (fHandle == NULL) { 00779 #ifdef WIN32 00780 if ((errstr = GetLastError ()) != 0) { 00781 jack_error ("can't load \"%s\": %ld", driver_desc->file, errstr); 00782 #else 00783 if ((errstr = dlerror ()) != 0) { 00784 jack_error ("can't load \"%s\": %s", driver_desc->file, errstr); 00785 #endif 00786 00787 } else { 00788 jack_error ("bizarre error loading driver shared object %s", driver_desc->file); 00789 } 00790 return NULL; 00791 } 00792 00793 fInitialize = (driverInitialize)GetDriverProc(fHandle, "driver_initialize"); 00794 00795 #ifdef WIN32 00796 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) { 00797 #else 00798 if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) { 00799 #endif 00800 jack_error("no initialize function in shared object %s\n", driver_desc->file); 00801 return NULL; 00802 } 00803 00804 fBackend = fInitialize(engine, synchro, params); 00805 return fBackend; 00806 } 00807