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.9.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);
   113         if (drv == (
struct driver*)NULL || name == NULL)
   114                 return (
struct driver*)NULL;
   115         if (strcasecmp(drv->
name, (
char*)name) == 0)
   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)
   302                 memcpy(&drv, &drv_null, 
sizeof(
struct driver));
   306         if (strcasecmp(name, 
"dev/input") == 0)
   310         if (found != (
struct driver*)NULL) {
   311                 memcpy(&drv, found, 
sizeof(
struct driver));
 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 fd
Set by the driver after init(). 
struct driver *(* plugin_guest_func)(const char *, drv_guest_func, void *)
Argument to for_each_plugin. 
Interface to the userspace drivers. 
#define log_warn(fmt,...)
Log a warning message. 
#define MAX_PLUGINS
Max number if plugins handled. 
const struct driver drv_null
Default driver, a placeholder. 
logchannel_t
Log channels used to filter messages. 
#define PLUGINDIR
Default directory for plugins/drivers. 
#define log_error(fmt,...)
Log an error message. 
void for_each_plugin(plugin_guest_func plugin_guest, void *arg, const char *pluginpath)
Apply func to all plugins (i. 
void hw_print_drivers(FILE *file)
Prints all drivers known to the system to the file given as argument. 
struct driver drv
Access to otherwise private drv. 
struct driver *(* drv_guest_func)(struct driver *, void *)
Argument to for_each_driver(). 
#define PLUGINDIR_VAR
Environment variable holding defaults for PLUGINDIR. 
int default_drvctl(unsigned int fd, void *arg)
Return DRV_ERR_NOTIMPLEMENTED. 
struct driver * for_each_driver(drv_guest_func func, void *arg, const char *pluginpath)
Apply func to all existing drivers. 
The data the driver exports i. 
int hw_choose_driver(const char *name)
Search for driver with given name, update global drv with driver data if found. 
const char * name
Driver name, as listed by -H help and used as argument to i –driver. 
int default_open(const char *path)
Stores path in drv.device if non-null. 
#define log_info(fmt,...)
Log an info message.