| 
							- /*
 - Copyright (C) 2001-2005 Paul Davis
 - Copyright (C) 2004-2006 Grame  
 - 
 - This program is free software; you can redistribute it and/or modify
 - it under the terms of the GNU General Public License as published by
 - the Free Software Foundation; either version 2 of the License, or
 - (at your option) any later version.
 - 
 - This program is distributed in the hope that it will be useful,
 - but WITHOUT ANY WARRANTY; without even the implied warranty of
 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - GNU General Public License for more details.
 - 
 - You should have received a copy of the GNU General Public License
 - along with this program; if not, write to the Free Software
 - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 - 
 - */
 - 
 - #ifdef WIN32 
 - #pragma warning (disable : 4786)
 - #endif
 - 
 - #include "JackDriverLoader.h"
 - #include "JackError.h"
 - #include <getopt.h>
 - 
 - #ifndef WIN32 
 - #include <dirent.h>
 - #endif
 - 
 - static void
 - jack_print_driver_options (jack_driver_desc_t * desc, FILE *file)
 - {
 -     unsigned long i;
 -     char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1];
 - 
 -     for (i = 0; i < desc->nparams; i++) {
 -         switch (desc->params[i].type) {
 -             case JackDriverParamInt:
 -                 //sprintf (arg_default, "%" PRIi32, desc->params[i].value.i);
 -                 sprintf (arg_default, "%" "i", desc->params[i].value.i);
 -                 break;
 -             case JackDriverParamUInt:
 -                 //sprintf (arg_default, "%" PRIu32, desc->params[i].value.ui);
 -                 sprintf (arg_default, "%" "u", desc->params[i].value.ui);
 -                 break;
 -             case JackDriverParamChar:
 -                 sprintf (arg_default, "%c", desc->params[i].value.c);
 -                 break;
 -             case JackDriverParamString:
 -                 if (desc->params[i].value.str && strcmp (desc->params[i].value.str, "") != 0)
 -                     sprintf (arg_default, "%s", desc->params[i].value.str);
 -                 else
 -                     sprintf (arg_default, "none");
 -                 break;
 -             case JackDriverParamBool:
 -                 sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false");
 -                 break;
 -         }
 - 
 -         fprintf (file, "\t-%c, --%s \t%s (default: %s)\n",
 -                  desc->params[i].character,
 -                  desc->params[i].name,
 -                  desc->params[i].short_desc,
 -                  arg_default);
 -     }
 - }
 - 
 - static void
 - jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file)
 - {
 -     fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n",
 -              desc->params[param].name, desc->name);
 -     fprintf (file, "%s\n", desc->params[param].long_desc);
 - }
 - 
 - EXPORT int
 - jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr)
 - {
 -     struct option * long_options;
 -     char * options, * options_ptr;
 -     unsigned long i;
 -     int opt;
 -     unsigned int param_index;
 -     JSList * params = NULL;
 -     jack_driver_param_t * driver_param;
 - 
 -     if (argc <= 1) {
 -         *param_ptr = NULL;
 -         return 0;
 -     }
 - 
 -     /* check for help */
 -     if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) {
 -         if (argc > 2) {
 -             for (i = 0; i < desc->nparams; i++) {
 -                 if (strcmp (desc->params[i].name, argv[2]) == 0) {
 -                     jack_print_driver_param_usage (desc, i, stdout);
 -                     return 1;
 -                 }
 -             }
 - 
 -             fprintf (stderr, "jackd: unknown option '%s' "
 -                      "for driver '%s'\n", argv[2],
 -                      desc->name);
 -         }
 - 
 -         printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name);
 -         jack_print_driver_options (desc, stdout);
 -         return 1;
 - 	}
 - 
 -     /* set up the stuff for getopt */
 -     options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char));
 -     long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option));
 - 
 -     options_ptr = options;
 -     for (i = 0; i < desc->nparams; i++) {
 -         sprintf (options_ptr, "%c::", desc->params[i].character);
 -         options_ptr += 3;
 -         long_options[i].name = desc->params[i].name;
 -         long_options[i].flag = NULL;
 -         long_options[i].val = desc->params[i].character;
 -         long_options[i].has_arg = optional_argument;
 -     }
 - 
 -     /* create the params */
 -     optind = 0;
 -     opterr = 0;
 -     while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
 - 
 -         if (opt == ':' || opt == '?') {
 -             if (opt == ':') {
 -                 fprintf (stderr, "Missing option to argument '%c'\n", optopt);
 -             } else {
 -                 fprintf (stderr, "Unknownage with option '%c'\n", optopt);
 -             }
 - 
 -             fprintf (stderr, "Options for driver '%s':\n", desc->name);
 -             jack_print_driver_options (desc, stderr);
 -             exit (1);
 -         }
 - 
 -         for (param_index = 0; param_index < desc->nparams; param_index++) {
 -             if (opt == desc->params[param_index].character) {
 -                 break;
 -             }
 -         }
 - 
 -         driver_param = (jack_driver_param_t*)calloc (1, sizeof (jack_driver_param_t));
 -         driver_param->character = desc->params[param_index].character;
 - 
 -         if (!optarg && optind < argc &&
 -                 strlen(argv[optind]) &&
 -                 argv[optind][0] != '-') {
 -             optarg = argv[optind];
 -         }
 - 
 -         if (optarg) {
 -             switch (desc->params[param_index].type) {
 -                 case JackDriverParamInt:
 -                     driver_param->value.i = atoi (optarg);
 -                     break;
 -                 case JackDriverParamUInt:
 -                     driver_param->value.ui = strtoul (optarg, NULL, 10);
 -                     break;
 -                 case JackDriverParamChar:
 -                     driver_param->value.c = optarg[0];
 -                     break;
 -                 case JackDriverParamString:
 -                     strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
 -                     break;
 -                 case JackDriverParamBool:
 - 
 -                     /*
 -                                 if (strcasecmp ("false", optarg) == 0 ||
 -                                         strcasecmp ("off", optarg) == 0 ||
 -                                         strcasecmp ("no", optarg) == 0 ||
 -                                         strcasecmp ("0", optarg) == 0 ||
 -                                         strcasecmp ("(null)", optarg) == 0 ) {
 -                     */ 
 -                     // steph
 -                     if (strcmp ("false", optarg) == 0 ||
 -                             strcmp ("off", optarg) == 0 ||
 -                             strcmp ("no", optarg) == 0 ||
 -                             strcmp ("0", optarg) == 0 ||
 -                             strcmp ("(null)", optarg) == 0 ) {
 -                         driver_param->value.i = false;
 - 
 -                     } else {
 - 
 -                         driver_param->value.i = true;
 - 
 -                     }
 -                     break;
 -             }
 -         } else {
 -             if (desc->params[param_index].type == JackDriverParamBool) {
 -                 driver_param->value.i = true;
 -             } else {
 -                 driver_param->value = desc->params[param_index].value;
 -             }
 -         }
 - 
 -         params = jack_slist_append (params, driver_param);
 -     }
 - 
 -     free (options);
 -     free (long_options);
 - 
 -     if (param_ptr)
 -         *param_ptr = params;
 - 
 -     return 0;
 - }
 - 
 - EXPORT jack_driver_desc_t *
 - jack_find_driver_descriptor (JSList * drivers, const char * name)
 - {
 -     jack_driver_desc_t * desc = 0;
 -     JSList * node;
 - 
 -     for (node = drivers; node; node = jack_slist_next (node)) {
 -         desc = (jack_driver_desc_t *) node->data;
 - 
 -         if (strcmp (desc->name, name) != 0) {
 -             desc = NULL;
 -         } else {
 -             break;
 -         }
 -     }
 - 
 -     return desc;
 - }
 - 
 - jack_driver_desc_t *
 - jack_drivers_get_descriptor (JSList * drivers, const char * sofile)
 - {
 -     jack_driver_desc_t * descriptor, * other_descriptor;
 -     JackDriverDescFunction so_get_descriptor = NULL;
 -     JSList * node;
 -     void * dlhandle;
 -     char * filename;
 - #ifdef WIN32
 -     int dlerr;
 - #else
 -     const char * dlerr;
 - #endif
 - 
 -     int err;
 - 	/*
 - 	char* driver_dir;
 -     if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
 - 		driver_dir = ADDON_DIR;
 -     }
 - 	*/
 -   
 - #ifdef WIN32
 - 	char* driver_dir = ADDON_DIR;
 -     if (strcmp(ADDON_DIR, "") == 0) {
 -         char temp_driver_dir1[512];
 -         char temp_driver_dir2[512];
 -         GetCurrentDirectory(512, temp_driver_dir1);
 -         sprintf(temp_driver_dir2, "%s/%s", temp_driver_dir1, ADDON_DIR);
 -         driver_dir = temp_driver_dir2;
 -     }
 - #else
 - 	char driver_dir[512];
 - 	snprintf(driver_dir,  sizeof(driver_dir) - 1, "%s/%s/jackmp", ADDON_DIR, LIB_DIR);
 - #endif
 - 
 -     filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1);
 -     sprintf (filename, "%s/%s", driver_dir, sofile);
 - 
 -     if ((dlhandle = LoadDriverModule(filename)) == NULL) {
 - #ifdef WIN32
 -         jack_error ("could not open driver .dll '%s': %ld\n", filename, GetLastError());
 - #else
 -         jack_error ("could not open driver .so '%s': %s\n", filename, dlerror());
 - #endif
 - 
 -         free(filename);
 -         return NULL;
 -     }
 - 
 -     so_get_descriptor = (JackDriverDescFunction)
 -                         GetProc(dlhandle, "driver_get_descriptor");
 - 
 - #ifdef WIN32
 -     if ((so_get_descriptor == NULL) && (dlerr = GetLastError()) != 0) {
 -         fprintf(stderr, "%ld\n", dlerr);
 - #else
 -     if ((so_get_descriptor == NULL) && (dlerr = dlerror ()) != NULL) {
 -         fprintf(stderr, "%s\n", dlerr);
 - #endif
 - 
 -         UnloadDriverModule(dlhandle);
 -         free(filename);
 -         return NULL;
 -     }
 - 
 -     if ((descriptor = so_get_descriptor ()) == NULL) {
 -         jack_error("driver from '%s' returned NULL descriptor\n", filename);
 -         UnloadDriverModule(dlhandle);
 -         free(filename);
 -         return NULL;
 -     }
 - 
 - #ifdef WIN32
 -     if ((err = UnloadDriverModule(dlhandle)) == 0) {
 -         jack_error ("error closing driver .so '%s': %ld\n", filename, GetLastError ());
 -     }
 - #else
 -     if ((err = UnloadDriverModule(dlhandle)) != 0) {
 -         jack_error ("error closing driver .so '%s': %s\n", filename, dlerror ());
 -     }
 - #endif
 - 
 -     /* check it doesn't exist already */
 -     for (node = drivers; node; node = jack_slist_next (node)) {
 -         other_descriptor = (jack_driver_desc_t *) node->data;
 - 
 -         if (strcmp(descriptor->name, other_descriptor->name) == 0) {
 -             jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first\n",
 -                         other_descriptor->file, filename, other_descriptor->name);
 -             /* FIXME: delete the descriptor */
 -             free(filename);
 -             return NULL;
 -         }
 -     }
 - 
 -     strncpy(descriptor->file, filename, PATH_MAX);
 -     free(filename);
 -     return descriptor;
 - }
 - 
 - #ifdef WIN32
 - 
 - EXPORT JSList *
 - jack_drivers_load (JSList * drivers) {
 -     char driver_dir[512];
 -     char dll_filename[512];
 -     WIN32_FIND_DATA filedata;
 -     HANDLE file;
 -     const char * ptr = NULL;
 -     JSList * driver_list = NULL;
 -     jack_driver_desc_t * desc;
 - 
 -     GetCurrentDirectory(512, driver_dir);
 - 
 -     sprintf(dll_filename, "%s/%s", ADDON_DIR, "*.dll");
 -     file = (HANDLE )FindFirstFile(dll_filename, &filedata);
 - 
 -     if (file == INVALID_HANDLE_VALUE) {
 -         printf("error\n");
 -         return NULL;
 -     }
 - 
 -     do {
 -         ptr = strrchr (filedata.cFileName, '.');
 -         if (!ptr) {
 -             continue;
 -         }
 -         ptr++;
 -         if (strncmp ("dll", ptr, 3) != 0) {
 -             continue;
 -         }
 - 
 -         desc = jack_drivers_get_descriptor (drivers, filedata.cFileName);
 -         if (desc) {
 -             driver_list = jack_slist_append (driver_list, desc);
 -         }
 - 
 -     } while (FindNextFile(file, &filedata));
 - 
 -     if (!driver_list) {
 -         jack_error ("could not find any drivers in %s!\n", driver_dir);
 -         return NULL;
 -     }
 - 
 -     return driver_list;
 - }
 - 
 - #else
 - 
 - JSList *
 - jack_drivers_load (JSList * drivers) {
 -     struct dirent * dir_entry;
 -     DIR * dir_stream;
 -     const char * ptr;
 -     int err;
 -     JSList * driver_list = NULL;
 -     jack_driver_desc_t * desc;
 - 
 - 	/*
 - 	char* driver_dir;
 -     if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
 -         driver_dir = ADDON_DIR;
 - 	}
 - 	*/
 - 	char driver_dir[512];
 - 	snprintf(driver_dir,  sizeof(driver_dir) - 1, "%s/%s/jackmp", ADDON_DIR, LIB_DIR);
 - 	
 -     /* search through the driver_dir and add get descriptors
 -     from the .so files in it */
 -     dir_stream = opendir (driver_dir);
 -     if (!dir_stream) {
 -         jack_error ("could not open driver directory %s: %s\n",
 -                     driver_dir, strerror (errno));
 -         return NULL;
 -     }
 - 
 -     while ((dir_entry = readdir(dir_stream))) {
 - 
 -         /* check the filename is of the right format */
 -         if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
 -             continue;
 -         }
 - 
 -         ptr = strrchr (dir_entry->d_name, '.');
 -         if (!ptr) {
 -             continue;
 -         }
 -         ptr++;
 -         if (strncmp ("so", ptr, 2) != 0) {
 -             continue;
 -         }
 - 
 -         desc = jack_drivers_get_descriptor (drivers, dir_entry->d_name);
 -         if (desc) {
 -             driver_list = jack_slist_append (driver_list, desc);
 -         }
 -     }
 - 
 -     err = closedir (dir_stream);
 -     if (err) {
 -         jack_error ("error closing driver directory %s: %s\n",
 -                     driver_dir, strerror (errno));
 -     }
 - 
 -     if (!driver_list) {
 -         jack_error ("could not find any drivers in %s!\n", driver_dir);
 -         return NULL;
 -     }
 - 
 -     return driver_list;
 - }
 - 
 - #endif
 - 
 - jack_driver_info_t *
 - jack_load_driver (jack_driver_desc_t * driver_desc) {
 - #ifdef WIN32
 -     int errstr;
 - #else
 -     const char * errstr;
 - #endif
 - 
 -     jack_driver_info_t *info;
 - 
 -     info = (jack_driver_info_t *) calloc (1, sizeof (*info));
 -     info->handle = LoadDriverModule (driver_desc->file);
 - 
 -     if (info->handle == NULL) {
 - #ifdef WIN32
 -         if ((errstr = GetLastError ()) != 0) {
 -             jack_error ("can't load \"%s\": %ld", driver_desc->file,
 -                         errstr);
 - #else
 -         if ((errstr = dlerror ()) != 0) {
 -             jack_error ("can't load \"%s\": %s", driver_desc->file,
 -                         errstr);
 - #endif
 - 
 -         } else {
 -             jack_error ("bizarre error loading driver shared "
 -                         "object %s", driver_desc->file);
 -         }
 -         goto fail;
 -     }
 - 
 -     info->initialize = (initialize)GetProc(info->handle, "driver_initialize");
 - 
 - #ifdef WIN32
 -     if ((info->initialize == NULL) && (errstr = GetLastError ()) != 0) {
 - #else
 -     if ((info->initialize == NULL) && (errstr = dlerror ()) != 0) {
 - #endif
 -         jack_error ("no initialize function in shared object %s\n",
 -                     driver_desc->file);
 -         goto fail;
 -     }
 - 
 -     return info;
 - 
 - fail:
 -     if (info->handle) {
 -         UnloadDriverModule(info->handle);
 -     }
 -     free (info);
 -     return NULL;
 - }
 
 
  |