Jack2 1.9.7
|
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 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 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 jack_log("Parameters for driver '%s' (all parameters are optional):", 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 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 jack_log("Parameters for driver '%s' (all parameters are optional):", 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_error("jack_get_descriptor : dll is not a driver, err = %ld", dlerr); 00440 #else 00441 if ((so_get_descriptor == NULL) && (dlerr = dlerror ()) != NULL) { 00442 jack_error("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 } else { 00567 jack_error ("jack_get_descriptor returns null for \'%s\'", filedata.cFileName); 00568 } 00569 00570 } while (FindNextFile(file, &filedata)); 00571 00572 if (!driver_list) { 00573 jack_error ("could not find any drivers in %s!", driver_dir); 00574 return NULL; 00575 } 00576 00577 return driver_list; 00578 } 00579 00580 #else 00581 00582 JSList * 00583 jack_drivers_load (JSList * drivers) { 00584 struct dirent * dir_entry; 00585 DIR * dir_stream; 00586 const char * ptr; 00587 int err; 00588 JSList * driver_list = NULL; 00589 jack_driver_desc_t * desc; 00590 00591 const char* driver_dir; 00592 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00593 driver_dir = ADDON_DIR; 00594 } 00595 00596 /* search through the driver_dir and add get descriptors 00597 from the .so files in it */ 00598 dir_stream = opendir (driver_dir); 00599 if (!dir_stream) { 00600 jack_error ("could not open driver directory %s: %s", 00601 driver_dir, strerror (errno)); 00602 return NULL; 00603 } 00604 00605 while ((dir_entry = readdir(dir_stream))) { 00606 00607 /* check the filename is of the right format */ 00608 if (strncmp ("jack_", dir_entry->d_name, 5) != 0) { 00609 continue; 00610 } 00611 00612 ptr = strrchr (dir_entry->d_name, '.'); 00613 if (!ptr) { 00614 continue; 00615 } 00616 ptr++; 00617 if (strncmp ("so", ptr, 2) != 0) { 00618 continue; 00619 } 00620 00621 desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor"); 00622 00623 if (desc) { 00624 driver_list = jack_slist_append (driver_list, desc); 00625 } else { 00626 jack_error ("jack_get_descriptor returns null for \'%s\'", dir_entry->d_name); 00627 } 00628 } 00629 00630 err = closedir (dir_stream); 00631 if (err) { 00632 jack_error ("error closing driver directory %s: %s", 00633 driver_dir, strerror (errno)); 00634 } 00635 00636 if (!driver_list) { 00637 jack_error ("could not find any drivers in %s!", driver_dir); 00638 return NULL; 00639 } 00640 00641 return driver_list; 00642 } 00643 00644 #endif 00645 00646 #ifdef WIN32 00647 00648 JSList * 00649 jack_internals_load (JSList * internals) { 00650 char * driver_dir; 00651 char driver_dir_storage[512]; 00652 char dll_filename[512]; 00653 WIN32_FIND_DATA filedata; 00654 HANDLE file; 00655 const char * ptr = NULL; 00656 JSList * driver_list = NULL; 00657 jack_driver_desc_t * desc; 00658 00659 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00660 // for WIN32 ADDON_DIR is defined in JackConstants.h as relative path 00661 GetCurrentDirectory(512, driver_dir_storage); 00662 strcat(driver_dir_storage, "/"); 00663 strcat(driver_dir_storage, ADDON_DIR); 00664 driver_dir = driver_dir_storage; 00665 } 00666 00667 sprintf(dll_filename, "%s/*.dll", driver_dir); 00668 00669 file = (HANDLE )FindFirstFile(dll_filename, &filedata); 00670 00671 if (file == INVALID_HANDLE_VALUE) { 00672 jack_error("error"); 00673 return NULL; 00674 } 00675 00676 do { 00677 00678 ptr = strrchr (filedata.cFileName, '.'); 00679 if (!ptr) { 00680 continue; 00681 } 00682 ptr++; 00683 if (strncmp ("dll", ptr, 3) != 0) { 00684 continue; 00685 } 00686 00687 /* check if dll is an internal client */ 00688 if (!check_symbol(filedata.cFileName, "jack_internal_initialize")) { 00689 continue; 00690 } 00691 00692 desc = jack_get_descriptor (internals, filedata.cFileName, "jack_get_descriptor"); 00693 if (desc) { 00694 driver_list = jack_slist_append (driver_list, desc); 00695 } else { 00696 jack_error ("jack_get_descriptor returns null for \'%s\'", filedata.cFileName); 00697 } 00698 00699 } while (FindNextFile(file, &filedata)); 00700 00701 if (!driver_list) { 00702 jack_error ("could not find any internals in %s!", driver_dir); 00703 return NULL; 00704 } 00705 00706 return driver_list; 00707 } 00708 00709 #else 00710 00711 JSList * 00712 jack_internals_load (JSList * internals) { 00713 struct dirent * dir_entry; 00714 DIR * dir_stream; 00715 const char * ptr; 00716 int err; 00717 JSList * driver_list = NULL; 00718 jack_driver_desc_t * desc; 00719 00720 const char* driver_dir; 00721 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) { 00722 driver_dir = ADDON_DIR; 00723 } 00724 00725 /* search through the driver_dir and add get descriptors 00726 from the .so files in it */ 00727 dir_stream = opendir (driver_dir); 00728 if (!dir_stream) { 00729 jack_error ("could not open driver directory %s: %s\n", 00730 driver_dir, strerror (errno)); 00731 return NULL; 00732 } 00733 00734 while ((dir_entry = readdir(dir_stream))) { 00735 00736 ptr = strrchr (dir_entry->d_name, '.'); 00737 if (!ptr) { 00738 continue; 00739 } 00740 ptr++; 00741 if (strncmp ("so", ptr, 2) != 0) { 00742 continue; 00743 } 00744 00745 /* check if dll is an internal client */ 00746 if (!check_symbol(dir_entry->d_name, "jack_internal_initialize")) { 00747 continue; 00748 } 00749 00750 desc = jack_get_descriptor (internals, dir_entry->d_name, "jack_get_descriptor"); 00751 if (desc) { 00752 driver_list = jack_slist_append (driver_list, desc); 00753 } else { 00754 jack_error ("jack_get_descriptor returns null for \'%s\'", dir_entry->d_name); 00755 } 00756 } 00757 00758 err = closedir (dir_stream); 00759 if (err) { 00760 jack_error ("error closing internal directory %s: %s\n", 00761 driver_dir, strerror (errno)); 00762 } 00763 00764 if (!driver_list) { 00765 jack_error ("could not find any internals in %s!", driver_dir); 00766 return NULL; 00767 } 00768 00769 return driver_list; 00770 } 00771 00772 #endif 00773 00774 Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc, 00775 Jack::JackLockedEngine* engine, 00776 Jack::JackSynchro* synchro, 00777 const JSList* params) 00778 { 00779 #ifdef WIN32 00780 int errstr; 00781 #else 00782 const char * errstr; 00783 #endif 00784 00785 fHandle = LoadDriverModule (driver_desc->file); 00786 00787 if (fHandle == NULL) { 00788 #ifdef WIN32 00789 if ((errstr = GetLastError ()) != 0) { 00790 jack_error ("can't load \"%s\": %ld", driver_desc->file, errstr); 00791 #else 00792 if ((errstr = dlerror ()) != 0) { 00793 jack_error ("can't load \"%s\": %s", driver_desc->file, errstr); 00794 #endif 00795 00796 } else { 00797 jack_error ("bizarre error loading driver shared object %s", driver_desc->file); 00798 } 00799 return NULL; 00800 } 00801 00802 fInitialize = (driverInitialize)GetDriverProc(fHandle, "driver_initialize"); 00803 00804 #ifdef WIN32 00805 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) { 00806 #else 00807 if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) { 00808 #endif 00809 jack_error("no initialize function in shared object %s\n", driver_desc->file); 00810 return NULL; 00811 } 00812 00813 fBackend = fInitialize(engine, synchro, params); 00814 return fBackend; 00815 } 00816 00817 JackDriverInfo::~JackDriverInfo() 00818 { 00819 delete fBackend; 00820 if (fHandle) 00821 UnloadDriverModule(fHandle); 00822 }