22 #ifdef GWINSZ_IN_SYS_IOCTL 
   23 # include <sys/ioctl.h> 
   27 #include "lirc/driver.h" 
   28 #include "lirc/drv_admin.h" 
   29 #include "lirc/lirc_options.h" 
   36 static const char* 
const PLUGIN_FILE_EXTENSION  = 
"so";
 
   40 #define MAX_PLUGINS  256 
   51 static void* last_plugin = NULL;
 
   56         .device         = 
"/dev/null",
 
   71         .driver_version = 
"0.10.2" 
   80 static int ends_with_so(
const char* str)
 
   82         char* dot = strrchr(str, 
'.');
 
   84         return (NULL == dot) ? 0 : strcmp(dot + 1, PLUGIN_FILE_EXTENSION) == 0;
 
   89 static int line_cmp(
const void* arg1, 
const void* arg2)
 
   91         return strcmp(*(
const char**)arg1, *(
const char**)arg2);
 
   96 static struct driver* add_hw_name(
struct driver* hw, 
void* arg)
 
   98         char_array* a = (char_array*)arg;
 
  104         a->array[a->size] = strdup(hw->
name);
 
  114                 return (
struct driver*)NULL;
 
  117         return (
struct driver*)NULL;
 
  129         if (last_plugin != NULL)
 
  130                 dlclose(last_plugin);
 
  131         last_plugin = dlopen(path, RTLD_NOW);
 
  132         if (last_plugin == NULL) {
 
  136         drivers = (
struct driver**)dlsym(last_plugin, 
"hardwares");
 
  137         if (drivers == (
struct driver**)NULL) {
 
  138                 log_warn(
"No hardwares entrypoint found in %s", path);
 
  140                 for (; *drivers; drivers++) {
 
  141                         if ((*drivers)->name == NULL) {
 
  142                                 log_warn(
"No driver name in %s", path);
 
  145                         result = (*func)(*drivers, arg);
 
  146                         if (result != (
struct driver*)NULL)
 
  155 static struct driver* for_each_plugin_in_dir(
const char*        dirpath,
 
  166         dir = opendir(dirpath);
 
  168                 log_info(
"Cannot open plugindir %s", dirpath);
 
  169                 return (
struct driver*)NULL;
 
  171         while ((ent = readdir(dir)) != NULL) {
 
  172                 if (!ends_with_so(ent->d_name))
 
  174                 strncpy(buff, dirpath, 
sizeof(buff) - 1);
 
  175                 if (buff[strlen(buff) - 1] == 
'/')
 
  176                         buff[strlen(buff) - 1] = 
'\0';
 
  177                 snprintf(path, 
sizeof(path),
 
  178                          "%s/%s", buff, ent->d_name);
 
  179                 result = plugin_guest(path, drv_guest, arg);
 
  180                 if (result != (
struct driver*)NULL)
 
  191                                     const char*         pluginpath_arg)
 
  193         const char* pluginpath;
 
  198         if (pluginpath_arg == NULL) {
 
  202                 if (pluginpath == NULL)
 
  205                 pluginpath = pluginpath_arg;
 
  207         if (strchr(pluginpath, 
':') == (
char*)NULL) {
 
  208                 return for_each_plugin_in_dir(pluginpath,
 
  213         tmp_path = alloca(strlen(pluginpath) + 1);
 
  214         strncpy(tmp_path, pluginpath, strlen(pluginpath) + 1);
 
  215         for (s = strtok(tmp_path, 
":"); s != NULL; s = strtok(NULL, 
":")) {
 
  216                 result = for_each_plugin_in_dir(s,
 
  220                 if (result != (
struct driver*)NULL)
 
  229                                const char* pluginpath)
 
  231         return for_each_path(visit_plugin, func, arg, pluginpath);
 
  237                      const char* pluginpath)
 
  239         for_each_path(plugin_guest, NULL, arg, pluginpath);
 
  244 static void get_columns(FILE* f, char_array names, 
int* cols, 
int* width)
 
  247         struct winsize winsize;
 
  252         if (!isatty(fileno(f)))
 
  254         if (ioctl(fileno(f), TIOCGWINSZ, &winsize) != 0)
 
  256         for (i = 0; i < names.size; i += 1) {
 
  257                 if (strlen(names.array[i]) > maxlen)
 
  258                         maxlen = strlen(names.array[i]);
 
  261         *cols = winsize.ws_col / maxlen;
 
  280                 fprintf(stderr, 
"Too many plugins (%d)\n", 
MAX_PLUGINS);
 
  283         qsort(names.array, names.size, 
sizeof(
char*), line_cmp);
 
  284         get_columns(file, names, &cols, &width);
 
  285         snprintf(format, 
sizeof(format), 
"%%-%ds", width);
 
  286         for (i = 0; i < names.size; i += 1) {
 
  287                 fprintf(file, format, names.array[i]);
 
  288                 if ((i + 1) % cols == 0)
 
  290                 free(names.array[i]);
 
  292         if ((i + 1) % cols != 0)
 
  306         if (strcasecmp(
name, 
"dev/input") == 0)
 
  310         if (found != (
struct driver*)NULL) {
 
  311                 memcpy(&
drv, found, 
sizeof(
struct driver));
 
Interface to the userspace drivers.
struct driver drv
Access to otherwise private drv.
int hw_choose_driver(const char *name)
Search for driver with given name, update global drv with driver data if found.
struct driver * for_each_driver(drv_guest_func func, void *arg, const char *pluginpath)
Apply func to all existing drivers.
#define MAX_PLUGINS
Max number if plugins handled.
const struct driver drv_null
Default driver, a placeholder.
void hw_print_drivers(FILE *file)
Prints all drivers known to the system to the file given as argument.
void for_each_plugin(plugin_guest_func plugin_guest, void *arg, const char *pluginpath)
Apply func to all plugins (i.
struct driver *(* drv_guest_func)(struct driver *, void *)
Argument to for_each_driver().
struct driver *(* plugin_guest_func)(const char *, drv_guest_func, void *)
Argument to for_each_plugin.
const char * ciniparser_getstring(dictionary *d, const char *key, char *def)
Get the string associated to a key.
int default_close(void)
For now, a placeholder.
int default_drvctl(unsigned int fd, void *arg)
Return DRV_ERR_NOTIMPLEMENTED.
int default_open(const char *path)
Stores path in drv.device if non-null.
#define PLUGINDIR
Default directory for plugins/drivers.
#define PLUGINDIR_VAR
Environment variable holding defaults for PLUGINDIR.
#define log_info(fmt,...)
Log an info message.
#define log_error(fmt,...)
Log an error message.
logchannel_t
Log channels used to filter messages.
#define log_warn(fmt,...)
Log a warning message.
The data the driver exports i.
int fd
Set by the driver after init().
const char * name
Driver name, as listed by -H help and used as argument to i –driver.